#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; } // 构造输出路径(保持相对目录结构) fs::path relativePath = fs::relative(imgPath, inputDir); fs::path outputPath = fs::path(outputDir) / relativePath; outputPath.replace_extension(".png"); // 统一保存为 PNG // 确保输出子目录存在 std::string outDir = outputPath.parent_path().string(); _sysmkdirs(outDir); // 保存 if (cv::imwrite(outputPath.string(), decoded)) { printf("OK → %s [%dx%d] (%ld ms)\n", outputPath.filename().c_str(), decoded.cols, decoded.rows, elapsed); successCount++; } else { printf("保存失败\n"); 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; }