#include #include #include #include "deal.h" #include #include #include #include #include "JpgDecoder.h" #include #include #include namespace fs = std::filesystem; void handler(int sig) { printf("Get handler sig"); string strcmd = "ps -ef | grep test_JBL_Check| awk '{print $2}' | xargs kill -9 "; const char *cmd = strcmd.c_str(); printf("delete test_JBL_Check success"); if (-1 == system(cmd)) { std::cout << "error" << std::endl; } // delete UnderCarriageCoreLogic::GetInstance(); exit(0); } int _sysmkdir(const std::string &dir) { int ret = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if (ret && errno == EEXIST) { // printf("dir[%s] already exist.\n", dir.c_str()); } else if (ret) { printf("create dir[%s] error: %d %s\n", dir.c_str(), ret, strerror(errno)); return -1; } else { printf("create dir[%s] success.\n", dir.c_str()); } return 0; } std::string __getParentDir(const std::string &dir) { std::string pdir = dir; if (pdir.length() < 1 || (pdir[0] != '/')) { return ""; } while (pdir.length() > 1 && (pdir[pdir.length() - 1] == '/')) pdir = pdir.substr(0, pdir.length() - 1); pdir = pdir.substr(0, pdir.find_last_of('/')); return pdir; } int _sysmkdirs(const std::string &dir) { int ret = 0; if (dir.empty()) return -1; std::string pdir; if ((ret = _sysmkdir(dir)) == -1) { pdir = __getParentDir(dir); if ((ret = _sysmkdirs(pdir)) == 0) { ret = _sysmkdirs(dir); } } return ret; } int main(int argc, char *argv[]) { deal test; if (argc > 1 && string(argv[1]) == "-h") { cout << "******************************************************" << endl; cout << "*** 1、./test_JBL_Check: 默认处理一套图 图片文件夹位于 ../data/img/t1,结果位于/home/aidlux/BOE/testresult" << endl; cout << "*** 2、./test_JBL_Check -s: 1 的基础上增加 过程存图,包括edge 和字符检测的中间结果存图,图片位于 当前文件夹。" << endl; cout << "*** 3、./test_JBL_Check -fjc filepath: 处理精测套图大图 结果位于/home/aidlux/BOE/ResultImg" << endl; cout << "*** 4、./test_JBL_Check -feai filepath num: 批量测试边缘检测算法,num 至多处理张数,结果:/home/aidlux/BOE/Edge" << endl; cout << "*** 5、./test_JBL_Check -falign filepath num : 批量测试定位算法,num 至多处理张数,结果:/home/aidlux/BOE/Align" << endl; cout << "*** 6、./test_JBL_Check -rjson filepath: 单张复测,filepath xx/xx/3A3K380001B1DK_20240408_152157_Main_0_2_L255" << endl; cout << "*** 6、./test_JBL_Check -rjsonall filepath: 一套图复测,filepath xx/xx/" << endl; cout << "*** 7、./test_CellAOI -decode [dir]: 批量解码 .ytimage → .png 到 /home/aidlux/BOE/CELL_AOI/decode_img" << endl; cout << "******************************************************" << endl; return 0; } printf("argc = %d\n", argc); for (int i = 0; i < argc; i++) { printf("argv[%d]=%s\n", i, argv[i]); } bool bDecodeMode = false; std::string decodeInputDir; if (argc > 1 && string(argv[1]) != "-h") { for (int i = 1; i < argc; i++) { if (string(argv[i]) == "-decode") { bDecodeMode = true; if (i + 1 < argc && argv[i + 1][0] != '-') { decodeInputDir = string(argv[i + 1]); i++; } } else if (string(argv[i]) == "-rs") { test.runConfig.run_Type = Process_Run_SaveImg; } else if (string(argv[i]) == "-rd") { test.runConfig.run_Type = Process_Run_Detect; } else if (string(argv[i]) == "-rjson") { if (i + 1 >= argc) { printf("error Not Path \n"); return -1; } test.runConfig.run_Type = Process_Run_ReJson; test.runConfig.filePath = string(argv[i + 1]); } else if (string(argv[i]) == "-f" && i + 1 < argc) { test.runConfig.det_Type = RUNTYPE_RUN_File; test.runConfig.filePath = string(argv[i + 1]); } else if (string(argv[i]) == "-fe" && i + 1 < argc) { test.runConfig.det_Type = RUNTYPE_RUN_EDGE_TEST; test.runConfig.filePath = string(argv[i + 1]); } else if (string(argv[i]) == "-feai" && i + 1 < argc) { test.runConfig.det_Type = RUNTYPE_RUN_EDGE_TEST_AI; test.runConfig.filePath = string(argv[i + 1]); } else if (string(argv[i]) == "-m") { test.runConfig.det_Type = RUNTYPE_RUN_Merge_Img; } if (string(argv[i]) == "-s") { test.runConfig.bSaveProcessImg = true; } if (string(argv[i]) == "-ud") { test.runConfig.bdecode = false; } if (string(argv[i]) == "-fud" && i + 1 < argc) { test.runConfig.det_Type = RUNTYPE_RUN_File; test.runConfig.filePath = string(argv[i + 1]); test.runConfig.bdecode = false; } } } // ====== 批量解码模式 (-decode) ====== if (bDecodeMode) { std::string inputDir = decodeInputDir.empty() ? std::string("../data/img/t1") : decodeInputDir; std::string outputDir = "/home/aidlux/BOE/CELL_AOI/decode_img"; printf("\n========== 批量解码模式 ==========\n"); printf(" 输入目录: %s\n", inputDir.c_str()); printf(" 输出目录: %s\n", outputDir.c_str()); printf("===================================\n\n"); // 检查输入目录 if (!fs::exists(inputDir) || !fs::is_directory(inputDir)) { printf("[decode] 输入目录不存在: %s\n", inputDir.c_str()); return -1; } // 创建输出目录 _sysmkdirs(outputDir); // 只解码 .ytimage 原始多JPEG文件 auto isYtimageFile = [](const std::string &ext) -> bool { std::string lower = ext; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); return (lower == ".ytimage"); }; // 扫描所有 .ytimage 文件 std::vector imageFiles; try { for (const auto &entry : fs::recursive_directory_iterator(inputDir)) { if (entry.is_regular_file() && isYtimageFile(entry.path().extension().string())) imageFiles.push_back(entry.path()); } } catch (const fs::filesystem_error &e) { printf("[decode] 扫描目录出错: %s\n", e.what()); return -1; } if (imageFiles.empty()) { printf("[decode] 未找到 .ytimage 文件: %s\n", inputDir.c_str()); return 0; } printf("[decode] 找到 %zu 个 .ytimage 文件,开始批量解码...\n", imageFiles.size()); // 逐个解码并保存 int successCount = 0; int failCount = 0; struct timeval tvTotalStart, tvTotalEnd; gettimeofday(&tvTotalStart, nullptr); for (size_t i = 0; i < imageFiles.size(); ++i) { const auto &imgPath = imageFiles[i]; std::string inputPath = imgPath.string(); printf("[%zu/%zu] %s ... ", i + 1, imageFiles.size(), imgPath.filename().c_str()); fflush(stdout); struct timeval tv1, tv2; gettimeofday(&tv1, nullptr); // ★ 调用 JpgDecoder 独立模块解码 cv::Mat decoded = decodeJpgImage(inputPath); gettimeofday(&tv2, nullptr); long elapsed = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec) / 1000; if (decoded.empty()) { printf("失败 (%ld ms)\n", elapsed); failCount++; continue; } // 提取 Product ID(文件路径往上两级目录) std::string productId = imgPath.parent_path().parent_path().filename().string(); // 文件名 stem(去掉 .ytimage 后缀) std::string stem = imgPath.stem().string(); // e.g. "CAA" // 输出目录:outputDir / ProductID fs::path outSubDir = fs::path(outputDir) / productId; _sysmkdirs(outSubDir.string()); // 保存两份:M_ 前缀 + A_ 前缀 bool ok = true; for (const auto &prefix : {"M_", "A_"}) { fs::path outPath = outSubDir / (std::string(prefix) + stem + ".png"); if (!cv::imwrite(outPath.string(), decoded)) { printf("保存失败: %s\n", outPath.filename().c_str()); ok = false; } } if (ok) { printf("OK → %s/M_%s.png + A_%s.png [%dx%d] (%ld ms)\n", productId.c_str(), stem.c_str(), stem.c_str(), decoded.cols, decoded.rows, elapsed); successCount++; } else { failCount++; } } gettimeofday(&tvTotalEnd, nullptr); long totalElapsed = (tvTotalEnd.tv_sec - tvTotalStart.tv_sec) * 1000 + (tvTotalEnd.tv_usec - tvTotalStart.tv_usec) / 1000; printf("\n========================================\n"); printf("[decode] 批量解码完成!\n"); printf(" 输入目录: %s\n", inputDir.c_str()); printf(" 输出目录: %s\n", outputDir.c_str()); printf(" 成功: %d 张\n", successCount); printf(" 失败: %d 张\n", failCount); printf(" 总耗时: %ld ms\n", totalElapsed); printf("========================================\n"); return (successCount > 0) ? 0 : -1; } test.runConfig.print("config"); // getchar(); signal(SIGINT, handler); test.start(); while (true) { usleep(10 * 1000); } return 0; }