|
|
#include <iostream>
|
|
|
#include <string>
|
|
|
#include <signal.h>
|
|
|
#include "deal.h"
|
|
|
#include <sys/types.h>
|
|
|
#include <sys/stat.h>
|
|
|
#include <unistd.h>
|
|
|
#include <string.h>
|
|
|
#include "JpgDecoder.h"
|
|
|
#include <filesystem>
|
|
|
#include <algorithm>
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
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<fs::path> 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;
|
|
|
}
|