#include "deal.h" #include "json/json.h" #include #include #include #include #include #include "CheckUtil.hpp" std::string ExtractFileNameWithoutExtension(const std::string &strImgPath) { // 查找最后一个斜杠 '/' 或 '\' 的位置 size_t lastSlashPos = strImgPath.find_last_of("/\\"); // 如果没有找到斜杠,默认整个字符串是文件名 std::string fileName = (lastSlashPos == std::string::npos) ? strImgPath : strImgPath.substr(lastSlashPos + 1); // 查找最后一个点 '.' 的位置 size_t lastDotPos = fileName.find_last_of('.'); // 如果没有找到点号,或者点号在第一个字符的位置,则返回完整文件名 if (lastDotPos == std::string::npos || lastDotPos == 0) { return fileName; } // 返回去掉扩展名的部分 return fileName.substr(0, lastDotPos); } std::string GetFileName(const std::string &strImgPath) { // 查找最后一个斜杠 '/' 或 '\' 的位置 size_t lastSlashPos = strImgPath.find_last_of("/\\"); // 如果没有找到斜杠,默认整个字符串是文件名 std::string fileName = (lastSlashPos == std::string::npos) ? strImgPath : strImgPath.substr(lastSlashPos + 1); // 查找最后一个点 '.' 的位置 return fileName; } bool customSort(const AI_Det_Channel_ &a, const AI_Det_Channel_ &b) { // 特定规则排序: "a" 排第一, "b" 排第二, "L" 排最后 if (a.strChannel == "Up-Particle" && b.strChannel != "Up-Particle") { return true; // "a" 排在前面 } if (a.strChannel != "Up-Particle" && b.strChannel == "Up-Particle") { return false; } if (a.strChannel == "Down-Particle" && b.strChannel != "Down-Particle" && b.strChannel != "Up-Particle") { return true; // "b" 排第二 } if (a.strChannel != "Down-Particle" && b.strChannel == "Down-Particle") { return false; } if (a.strChannel == "L0" && b.strChannel != "L0" && b.strChannel != "Up-Particle" && b.strChannel != "Down-Particle") { return false; // "L" 排最后 } if (a.strChannel != "L0" && b.strChannel == "L0") { return true; } // 对其他情况使用字典顺序排序 return a.strChannel < b.strChannel; } // 定义图片读取函数 void readImage(const std::string &filename) { cv::Mat image = cv::imread(filename); if (image.empty()) { std::cerr << "Error: Unable to read image " << filename << std::endl; return; } // // 在这里可以添加对图像的处理操作 // // 例如:显示图像、保存图像、进行其他处理等 // // 示例:显示图像 // cv::imshow(filename, image); // cv::waitKey(0); // cv::destroyWindow(filename); } int _sysmkdir_1(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_1(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_1(const std::string &dir) { int ret = 0; if (dir.empty()) return -1; std::string pdir; if ((ret = _sysmkdir_1(dir)) == -1) { pdir = __getParentDir_1(dir); if ((ret = _sysmkdirs_1(pdir)) == 0) { ret = _sysmkdirs_1(dir); } } return ret; } long getcurTime() { struct timeval tv; gettimeofday(&tv, NULL); return ((long)tv.tv_sec) * 1000 + ((long)tv.tv_usec) / 1000; } deal::deal() { nLastCheckAnalysisyThreadIdx = 0; m_nCamIdx = 0; m_nCurUseCPUIDX = 0; m_nSaveDetprocessImg = 0; m_DetResult.Init(); for (int i = 0; i < READ_IMG_THREAD_NUM; i++) { m_nReadStausList[i] = ReadImg_Status_IDE; } m_nreadImg_Stop = false; m_strCurDate = ""; m_nReadThread_type = READ_THREAD_TYPE_NULL; for (int i = 0; i < Status_Type_Count; i++) { m_DetStatusList[i] = Thread_Status_IDE; } m_nTestNum = 9999999; m_pALLImgCheckAnalysisy = NULL; m_pextractImg = NULL; } deal::~deal() { } int deal::start() { std::string strdate = CheckUtil::getCurrentDate(); printf("===== %s\n", strdate.c_str()); int re = Init(); // getchar(); // 配置系统运行的cup核数。 if (re != 0) { return 1; } // 解析图片,并保存 if (Process_Run_SaveImg == runConfig.run_Type) { Testsaveimg(); return 1; } else if (runConfig.run_Type == Process_Run_ReJson) { ReJson_ALL(); return 0; } else { DetImg(); } return 0; } int deal::Init() { InitCPUIDX(); // 读取系统配置文件 int re = ReadSystemConfig(FILE_SYSTEM_RUN_CONFIG); if (re == false) { printf("ReadSystemConfig error\n"); return 1; } // 加载 检测 的通道 图片名称 std::string strchannlePath = m_system_param.config_Root_Path + "surface_list.json"; m_image_ReadChannel.ReadJsonConfig(strchannlePath); // getchar(); // 如果是 cell aoi 需要 加载初始化 图片解密 库 InitExtractImg(); if (Process_Run_SaveImg == runConfig.run_Type) { return 0; } // getchar(); // 初始化参数模块 InitConfig(); printf("\n\n\n\n\n\n\n\n\n\n\n**********************************************************LoadCheckImgConfig\n"); // 载入参数 re = LoadCheckImgConfig(); if (re != 0) { printf("read config error\n"); return 2; } printf("\n\n**********************************************************InitCheckAnalysisy\n"); // 初始化检测库 InitCheckAnalysisy(); printf("\n\n\n\n\n\n\n\n\n\n\n**********************************************************Check\n"); return 0; } int deal::LoadCheckImgConfig() { int re = LoadAnalysisConfig(); if (re != 0) { return re; } // re = LoadCheckConfig(); // if (re != 0) // { // return re; // } return 0; } int deal::InitCheckAnalysisy() { int re = 0; int m_nMAX_GPU_NUM = MAX_GPU_NUM; if (m_nMAX_GPU_NUM <= 0) { printf(">>>>error GPU error %d \n", m_nMAX_GPU_NUM); return 2; } int startidx = m_CPUInfo[THREAD_CPU_CheckSo].startIdx; int cpunum = m_CPUInfo[THREAD_CPU_CheckSo].num; m_RunConfig.nCpu_start_Idx = startidx; m_RunConfig.nCpu_num = cpunum; m_pALLImgCheckAnalysisy = ALLImgCheckBase::GetInstance(); re = m_pALLImgCheckAnalysisy->UpdateConfig((void *)&m_RunConfig, CHECK_CONFIG_Run); re = m_pALLImgCheckAnalysisy->UpdateConfig((void *)m_pConfigManager, CHECK_CONFIG_Module); VERSION_INFO tm; tm.InterfaceVersion = ALL_INTERFACE_VERSION; tm.ConfigVersion = CONFIGBASE_VERSION; tm.ResultVersion = RESULT_VERSION; re = m_pALLImgCheckAnalysisy->RunStart(&tm); if (re != 0) { printf("RunStart Fail %d\n", re); return re; } printf(">>>> ImgCheckThread Start Succ \n"); return 0; } int deal::InitConfig() { m_pConfigManager = ConfigManagerBase::GetInstance(); return 0; } int deal::InitExtractImg() { m_pextractImg = ExtractBase::GetInstance(); // cv::Mat outimg; // m_pextractImg->ReadCELLImg("/mnt/4116e2a5-46a0-4c3e-a6e2-ed30d3ed7012/downloads/TestSets02/Cell AOI/20250627/研磨划伤和圈印/27圈印/6L7F52D001A2AEA/CA_20250508074237.ytimage",outimg); return 0; } int deal::InitSaveImgPath() { return 0; } int deal::LoadCheckConfig() { return 0; } int deal::LoadAnalysisConfig() { if (!m_pConfigManager) { return 1; } std::string folder = m_system_param.config_Root_Path; int re = m_pConfigManager->LoadAnalysisConfig(folder); // for (const auto &pair : m_pConfigManager->Config_instances_) // { // std::cout << "cam: " << pair.first << std::endl; // } // getchar(); return re; } int deal::StartThread(THREAD_RUN_TYPE type) { m_bExit = false; // 只读图线程 if (type == THREAD_RUN_ALL) { // 开启检测线程 ptr_DealImgthread = std::make_shared(&deal::DealImg, this); // 结果处理线程 // ptr_Resultthread = std::make_shared(&deal::ResultThread, this); for (int i = 0; i < Save_IMG_THREAD_NUM; ++i) { // 创建线程,并使用 std::make_shared 创建 shared_ptr std::shared_ptr threadPtr = std::make_shared(&deal::ResultThread, this, i); // 将 shared_ptr 添加到 vector 中 ptr_ResultthreadList.push_back(threadPtr); } // 结果拷贝线程 ptr_GetResultthread = std::make_shared(&deal::GetResultThread, this); } for (int i = 0; i < READ_IMG_THREAD_NUM; ++i) { // 创建线程,并使用 std::make_shared 创建 shared_ptr std::shared_ptr threadPtr = std::make_shared(&deal::ReadImgThread, this, i); // 将 shared_ptr 添加到 vector 中 threadArray.push_back(threadPtr); } return 0; } int deal::StopThread() { return 0; } int deal::preCheck() { string cur_time = CheckUtil::getCurTimeHMS(); printf("[%s]>>> preCheck start \n", cur_time.c_str()); std::string strRoot = "../data/img/t1"; std::string strProductID = ""; std::string strRoot2 = "../data/img/t1"; { READ_IMG_INFO read; readTestImg(read); strRoot = read.strpath; strProductID = read.strproduct; strRoot2 = read.strpath_2; printf("strSearchImg strRoot %s\n", strRoot.c_str()); std::ifstream file123(strRoot); bool bhave = file123.good(); if (!bhave) { printf("read img path error %d %s\n", bhave, strRoot.c_str()); return 1; } } // 获取图片路径 std::string strSearchImg = strRoot; Read_Image dfe; int re = 0; dfe.pimage_ReadChannel = &m_image_ReadChannel; if (strRoot2 != "") { re = dfe.Read_Image_List(strSearchImg, strRoot2, strProductID); } else { re = dfe.Read_Image_List(strSearchImg, strProductID); } if (re != 0) { return re; } if (dfe.m_product_Camera_List.size() <= 0) { printf("error m_product_Camera_List.size() %ld \n", dfe.m_product_Camera_List.size()); return -1; } int idx = 0; for (int i = 0; i < dfe.m_product_Camera_List.size(); i++) { if (dfe.m_product_Camera_List[i]->strProductID == strProductID) { idx = i; break; } } std::shared_ptr product = dfe.m_product_Camera_List[idx]; int AllImgNum = product->getImgNum(); printf("product %s img num %d \n", product->strProductID.c_str(), AllImgNum); long t1 = getcurTime(); // 读图现场都开启 setReadThreadStart(); // 遍历所有图片 开始读图处理 AllImgNum = 0; for (const auto pcam : product->camera_list) { std::shared_ptr tem = std::make_shared(); tem->strCamID = pcam->strCamName; for (const auto pimage : pcam->image_list) { tem->strchannelName = pimage->strchannelName; tem->strName = pimage->strName; tem->strProductID = pimage->strProductID; if (tem->strPath == "") { tem->strPath = pimage->strPath; } else { tem->strPath_B = pimage->strPath; } } InsertReadImgInfo(tem); AllImgNum++; // break; } // AllImgNum = 1; { IN_IMG_Status_ temstatus = IN_IMG_Status_Start; std::shared_ptr tempDetImageInfo = nullptr; int pushImgNum = 0; long det_time_start = getcurTime(); std::string strImgSN = strProductID; int GetImgNum = 0; while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); // int ThreadIdx = GetReadImgCompleteThreadIdx(); if (ThreadIdx < 0) { continue; } std::shared_ptr pDetImageInfo = nullptr; pDetImageInfo = m_ReadImgThread_Result[ThreadIdx]; // 开始送到检测进行处理 if (pDetImageInfo != nullptr) { // printf(">>> %s----start \n", pDetImageInfo->strName.c_str()); tempDetImageInfo = pDetImageInfo; int re = SendImgToCheck(pDetImageInfo, temstatus); if (re != 0) { continue; } } SetStatus_List(ThreadIdx, Thread_Status_READY); GetImgNum++; if (IN_IMG_Status_Start == temstatus) { temstatus = IN_IMG_Status_Other; } // 图是否都读取完了。 bool bReadCompleted = false; if (GetImgNum >= AllImgNum) { bReadCompleted = true; } // 退出 if (bReadCompleted) { SendImgToCheck(tempDetImageInfo, IN_IMG_Status_End); break; } } string cur_time = CheckUtil::getCurTimeHMS(); printf("[%s]>>> preCheck push img end \n", cur_time.c_str()); int getresultNum = 0; while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费过程 // 处理结果 std::shared_ptr checkResult; int re = m_pALLImgCheckAnalysisy->GetCheckReuslt(checkResult); saveImg("/home/aidlux/BOE/CELL_AOI/testresult/", checkResult); getresultNum++; if (getresultNum == pushImgNum) { break; } } } printf(">>> ALL preCheck complete \n"); return 0; } int deal::Testsaveimg() { printf(">>> preCheck start \n"); std::string strRoot = "../data/img/t1"; std::string strProductID = ""; { READ_IMG_INFO read; readTestImg(read); strRoot = read.strpath; strProductID = read.strproduct; printf("strSearchImg strRoot %s\n", strRoot.c_str()); std::ifstream file123(strRoot); bool bhave = file123.good(); if (!bhave) { printf("read img path error %d %s\n", bhave, strRoot.c_str()); return 1; } } // 获取图片路径 std::string strSearchImg = strRoot; Read_Image dfe; dfe.pimage_ReadChannel = &m_image_ReadChannel; int re = dfe.Read_Image_List(strSearchImg, strProductID); if (re != 0) { return re; } if (dfe.m_product_Camera_List.size() <= 0) { return -1; } int idx = 0; for (int i = 0; i < dfe.m_product_Camera_List.size(); i++) { if (dfe.m_product_Camera_List[i]->strProductID == strProductID) { idx = i; break; } } std::shared_ptr product = dfe.m_product_Camera_List[idx]; int AllImgNum = product->getImgNum(); printf("product %s img num %d \n", product->strProductID.c_str(), AllImgNum); long t1 = getcurTime(); // 读图现场都开启 for (const auto pcam : product->camera_list) { for (const auto pimage : pcam->image_list) { cv::Mat img; long t1 = CheckUtil::getcurTime(); re = m_pextractImg->ReadCELLImg(pimage->strPath, img, runConfig.bdecode); long t2 = CheckUtil::getcurTime(); printf("read re = %d img time %ld ms \n", re, t2 - t1); if (!img.empty()) { cv::imwrite(pimage->strName + ".jpg", img); } else { printf("img.empty() \n"); } // getchar(); } } return 0; } std::string deal::readTestImg() { std::string strRoot = "../data/img/TestImg.json"; printf("Reading Img config %s\n", strRoot.c_str()); Json::CharReaderBuilder builder; builder["collectComments"] = true; Json::Value root; std::string err; std::ifstream ifs(strRoot); if (!ifs.is_open()) { printf("error:file is open\n"); return ""; } if (!Json::parseFromStream(builder, ifs, &root, &err)) { printf("error:parseFromStream\n"); return ""; } std::string imgpath = ""; imgpath = root["TestImg_Path"].asString(); return imgpath; } int deal::readTestImg(READ_IMG_INFO &read) { std::string strRoot = "../data/img/TestImg.json"; printf("Reading Img config %s\n", strRoot.c_str()); Json::CharReaderBuilder builder; builder["collectComments"] = true; Json::Value root; std::string err; std::ifstream ifs(strRoot); if (!ifs.is_open()) { printf("error:file is open\n"); return 1; } if (!Json::parseFromStream(builder, ifs, &root, &err)) { printf("error:parseFromStream\n"); return 1; } std::string imgpath = ""; read.strpath = root["TestImg_Path"].asString(); read.strproduct = root["ProductID"].asString(); if (root["TestImg_2_Path"]) { read.strpath_2 = root["TestImg_2_Path"].asString(); } else { read.strpath_2 = ""; } return 0; } int deal::repeatCheck() { return 0; } int deal::saveImg(std::string strpath, std::shared_ptr result) { std::string strroot = strpath; std::string strroot_qx = strpath; if (result->in_shareImage->imgstr != "") { strroot += result->in_shareImage->imgstr; strroot += "/"; strroot_qx += result->in_shareImage->imgstr; strroot_qx += "/"; } if (strpath != "") { strroot_qx += "qx/"; if (result->nProductResult != 0) { strroot += "NG/"; } else { strroot += "OK/"; } if (result->in_shareImage->strImgProductID != "") { strroot += result->in_shareImage->strImgProductID + "/"; } if (result->nresult != 0) { strroot += "NG/"; } else { if (result->nYS_result != 0) { strroot += "OK/YS/"; } else { strroot += "OK/OK/"; } } } printf("result->nresult %d %d \n", result->nresult, result->nYS_result); printf("%s\n", strroot.c_str()); _sysmkdirs_1(strroot); std::string str_saveName = ""; // getchar(); if (result->in_shareImage->strImgProductID != "") { strroot += result->in_shareImage->strImgProductID; str_saveName += result->in_shareImage->strImgProductID; } if (result->in_shareImage->strImgName != "") { strroot += "_" + result->in_shareImage->strImgName; str_saveName += "_" + result->in_shareImage->strImgName; } { std::string strcam = std::to_string(result->in_shareImage->camera_ID); strroot += "_" + strcam; str_saveName += "_" + strcam; } writeLog(strroot, result->det_LogList); WriteJsonString(strroot, result->strResultJson); // printf("%s \n", strroot.c_str()); std::string str = strroot + "_RE_Resultimg.png"; if (!result->resultimg.empty()) { cv::imwrite(str, result->resultimg); } std::string str123 = strroot + "_RE_CutImg.png"; if (!result->cutSrcimg.empty()) { cv::imwrite(str123, result->cutSrcimg); } std::string str123r = strroot + "_RE_CutDrawImg.png"; if (!result->SrcResultImg.empty()) { cv::imwrite(str123r, result->SrcResultImg); } std::string strMask = strroot + "_RE_AIMask.png"; if (!result->resultMaskImg.empty()) { cv::imwrite(strMask, result->resultMaskImg); } std::string str_qx; printf("result->qxImageResult.size() %ld \n", result->qxImageResult.size()); for (int i = 0; i < result->qxImageResult.size(); i++) { std::string str = strroot + "_RE_" + std::to_string(i) + "_Src.png"; if (!result->qxImageResult.at(i).srcImg.empty()) { cv::imwrite(str, result->qxImageResult.at(i).srcImg); } str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/"; printf("-1-- %s\n", str_qx.c_str()); _sysmkdirs_1(str_qx); str_qx += str_saveName + "_RE_" + std::to_string(i) + "_Src.png"; // printf("-2-- %s\n", str_qx.c_str()); if (!result->qxImageResult.at(i).srcImg.empty()) { cv::imwrite(str_qx, result->qxImageResult.at(i).srcImg); } str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/"; str_qx += str_saveName + "_RE_" + std::to_string(i) + "_Small.png"; if (!result->qxImageResult.at(i).resizeImg.empty()) { cv::imwrite(str_qx, result->qxImageResult.at(i).resizeImg); } { str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/"; str_qx += str_saveName + "_RE_" + std::to_string(i) + "_AI_In.png"; if (!result->qxImageResult.at(i).AI_in_Img.empty()) { cv::imwrite(str_qx, result->qxImageResult.at(i).AI_in_Img); } str_qx = strroot_qx + result->qxImageResult.at(i).strTypeName + "/"; str_qx += str_saveName + "_RE_" + std::to_string(i) + "_AI_In_mask.png"; if (!result->qxImageResult.at(i).AI_out_img.empty()) { cv::imwrite(str_qx, result->qxImageResult.at(i).AI_out_img); } } // printf("-1111-- %s\n", str_qx.c_str()); std::string str1 = strroot + "_RE_" + std::to_string(i) + "_Small.png"; if (!result->qxImageResult.at(i).resizeImg.empty()) { cv::imwrite(str1, result->qxImageResult.at(i).resizeImg); } } printf("result->YS_ImageResult.size() %ld\n", result->YS_ImageResult.size()); for (int i = 0; i < result->YS_ImageResult.size(); i++) { std::string str = strroot + "_RE_" + std::to_string(i) + "_YS_Src.png"; if (result->YS_ImageResult.at(i).srcImg.empty()) { printf("resqwwwwwwwwwwwwwwwult->YS_ImageResult.size() %ld \n", result->YS_ImageResult.size()); } if (!result->YS_ImageResult.at(i).srcImg.empty()) { cv::imwrite(str, result->YS_ImageResult.at(i).srcImg); } str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/"; // printf("-3-- %s\n", str_qx.c_str()); _sysmkdirs_1(str_qx); str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_Src.png"; // printf("-4-- %s\n", str_qx.c_str()); if (!result->YS_ImageResult.at(i).srcImg.empty()) { cv::imwrite(str_qx, result->YS_ImageResult.at(i).srcImg); } str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/"; str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_Small.png"; if (!result->YS_ImageResult.at(i).resizeImg.empty()) { cv::imwrite(str_qx, result->YS_ImageResult.at(i).resizeImg); } { str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/"; str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_AI_In.png"; if (!result->YS_ImageResult.at(i).AI_in_Img.empty()) { cv::imwrite(str_qx, result->YS_ImageResult.at(i).AI_in_Img); } str_qx = strroot_qx + result->YS_ImageResult.at(i).strTypeName + "/"; str_qx += str_saveName + "_RE_" + std::to_string(i) + "_YS_AI_In_mask.png"; if (!result->YS_ImageResult.at(i).AI_out_img.empty()) { cv::imwrite(str_qx, result->YS_ImageResult.at(i).AI_out_img); } } // printf("-1111-- %s\n", str_qx.c_str()); std::string str1 = strroot + "_RE_" + std::to_string(i) + "_YS_Small.png"; if (!result->YS_ImageResult.at(i).resizeImg.empty()) { cv::imwrite(str1, result->YS_ImageResult.at(i).resizeImg); } } return 0; } int deal::writeLog(std::string strSavePath, std::vector logList) { std::string str = strSavePath + ".txt"; // 打开文件 std::ofstream outFile(str); // 检查文件是否成功打开 if (!outFile) { std::cerr << "Failed to open file." << std::endl; return 1; } // 将vector中的内容写入文件 for (const auto &str : logList) { // printf("%s \n",str.c_str()); outFile << str << std::endl; } // 关闭文件 outFile.close(); return 0; } int deal::WriteJsonString(std::string strSavePath, std::string strjson) { std::string str = strSavePath + ".json"; // 打开文件 std::ofstream outFile(str); // 检查文件是否成功打开 if (!outFile) { std::cerr << "Failed to open file." << std::endl; return 1; } // 将vector中的内容写入文件 outFile << strjson << std::endl; // 关闭文件 outFile.close(); return 0; } void deal::ResultThread(int id) { std::vector vi; int startidx = m_CPUInfo[THREAD_CPU_Main_saveImg].startIdx; int cpunum = m_CPUInfo[THREAD_CPU_Main_saveImg].num; // for (int i = 0; i < cpunum; i++) // { // vi.push_back(startidx + i); // } vi.push_back(startidx + id); auto nRet = set_cpu_id(vi); printf("THREAD_CPU_Main_saveImg %d bind cpu ret %d startidx %d num %d\n", id, nRet, startidx + id, 1); int re = 0; cv::Mat detImg; int kkkkk = 0; static int saveidx = 0; while (!m_bExit) { std::shared_ptr dealResult; mutex_Result_list.lock(); if (m_Result_list.size() > 0) { dealResult = m_Result_list.front(); m_Result_list.pop(); if (m_Result_list.size() > 10) { printf("Result_list size %ld \n", m_Result_list.size()); } mutex_Result_list.unlock(); } else { mutex_Result_list.unlock(); usleep(10000); continue; } { updataResltInfo(dealResult); } { if (true) { // 存图 // std::string savepath = "/home/aidlux/BOE/Detsave/" + runConfig.filePath + "/"; // saveImg(savepath, dealResult); saveImg("/home/aidlux/BOE/CELL_AOI/Detsave/", dealResult); } { // 存 检测统计 日志 mutex_DetResult_.lock(); m_DetResult.print(false); std::string strlog = "/home/aidlux/BOE/CELL_AOI/ResultImg/"; if (m_strCurDate != "") { strlog += m_strCurDate; strlog += "/result"; } else { strlog += "/result"; } writeLog(strlog, m_DetResult.strlist); mutex_DetResult_.unlock(); } } usleep(5 * 1000); } } int deal::set_cpu_id(const std::vector &cpu_set_vec) { // for cpu affinity int nRet = 0; #ifdef __linux cpu_set_t _cur_cpu_set; CPU_ZERO(&_cur_cpu_set); for (auto _id : cpu_set_vec) { CPU_SET(_id, &_cur_cpu_set); } if (0 > pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &_cur_cpu_set)) { perror("set cpu affinity failed: "); printf("Warning: set cpu affinity failed ... ...\n"); nRet = -1; } #endif //__linux return nRet; } void deal::GetDealResultToQueu() { // 处理结果 std::shared_ptr checkResult; if (!m_pALLImgCheckAnalysisy) { return; } int re = m_pALLImgCheckAnalysisy->GetCheckReuslt(checkResult); if (re == 0) { mutex_Result_list.lock(); m_Result_list.push(checkResult); mutex_Result_list.unlock(); } else { printf("Check error >>>>>>>>>>>>>>>>> \n"); } return; } bool deal::ReadSystemConfig(const std::string &strPath) { printf("Reading system config %s\n", strPath.c_str()); Json::CharReaderBuilder builder; builder["collectComments"] = true; Json::Value root; std::string err; std::ifstream ifs(strPath); if (!ifs.is_open()) { printf("error:file is open\n"); return false; } if (!Json::parseFromStream(builder, ifs, &root, &err)) { printf("error:parseFromStream\n"); return false; } m_system_param.Use_CPU_StartIdx = root["Use_CPU_StartIdx"].asInt(); // path m_system_param.Analysis_Config_path = root["Analysis_Config_path"].asString(); m_system_param.Analysis_Config_path_Cam2 = root["Analysis_Config_path_Cam2"].asString(); m_system_param.config_Root_Path = root["Config_Root_Path"].asString(); m_system_param.Check_Config_path = root["Check_Config_path"].asString(); m_system_param.preCheckImg_Path = root["preCheckImg_Path"].asString(); m_system_param.preCHeck_YX = root["preCHeck_YX"].asInt(); m_system_param.preCHeck_defect = root["preCHeck_defect"].asInt(); m_nCurUseCPUIDX = m_system_param.Use_CPU_StartIdx; return m_system_param.valid(); } int deal::GetJcImageInfo(std::string strpath, std::vector &jcImageInfoList) { LoadOfflineCheckImg(strpath); jcImageInfoList.erase(jcImageInfoList.begin(), jcImageInfoList.end()); // 遍历每一套图片 for (int idx = 0; idx < m_OffLineCheckImgNameList.size(); idx++) { std::string path = m_OffLineCheckImgNameList.at(idx); JC_IMAGE_INFO_ tem; int re = GetImgInfo_POL_ET(path, &tem); } // getchar(); return 0; } int deal::GetDetImageInfo(std::string strProductID, std::string strSearchImg, std::vector &jcImageInfoList) { // 1、获取图片路径 std::vector img_paths; std::string strs1 = strSearchImg + "/*.ytimage"; if(!runConfig.bdecode) { strs1 = strSearchImg + "/*.jpg"; } cv::glob(strs1, img_paths, true); // printf("%ld \n", img_paths.size()); jcImageInfoList.erase(jcImageInfoList.begin(), jcImageInfoList.end()); // 遍历每一套图片 for (int idx = 0; idx < img_paths.size(); idx++) { // printf("---- %d / %d %s----\n", idx, m_OffLineCheckImgNameList.size(), m_OffLineCheckImgNameList.at(idx).c_str()); std::string path = img_paths.at(idx); JC_IMAGE_INFO_ tem; int re = 0; { re = GetImgInfo_POL_ET(path, &tem); if (re != 0) { continue; } } tem.strProductID = strProductID; jcImageInfoList.push_back(tem); } return 0; } int deal::GetImgInfo_POL_ET(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo) { if (pImageInfo == NULL) { return 1; } string strName = ""; size_t lastUnderscore; strName = ExtractFileNameWithoutExtension(strImgPath); printf("strName %s \n", strName.c_str()); std::string strImageChannel; // 使用 find 检查是否包含 "CA" 或 "TA" if (strName.find("CA") != std::string::npos || strName.find("CF") != std::string::npos) { strImageChannel = "CA"; } else if (strName.find("TA") != std::string::npos || strName.find("TFT") != std::string::npos) { strImageChannel = "TA"; } else { return 1; } printf("strImageChannel %s\n", strImageChannel.c_str()); pImageInfo->strchannelName = strImageChannel; pImageInfo->strName = strName; pImageInfo->strPath = strImgPath; pImageInfo->strCamID = strImageChannel; printf("strImgPath %s strName %s strChannel %s\n", strImgPath.c_str(), strName.c_str(), strImageChannel.c_str()); return 0; } int deal::GetImgInfo_POL_ET_PNG(std::string strImgPath, JC_IMAGE_INFO_ *pImageInfo) { if (pImageInfo == NULL) { return 1; } string strImageChannel = ExtractFileNameWithoutExtension(strImgPath); printf("strImageChannel %s\n", strImageChannel.c_str()); std::string strChannle = m_image_ReadChannel.strDetName(strImageChannel); if (strChannle == "") { return 1; } pImageInfo->strchannelName = strChannle; pImageInfo->strName = strChannle; pImageInfo->strPath = strImgPath; pImageInfo->strCamID = "0"; // printf("strImgPath %s strChannel %s\n", strImgPath.c_str(), strChannle.c_str()); // 使用 find 函数检查是否包含 "_左" if (strImgPath.find("_工位右") != std::string::npos) { pImageInfo->strCamID = "1"; ; } return 0; } int deal::ReadTestImgaData() { std::string strPath = "../data/testImg.json"; printf("ReadTestImgaData config %s\n", strPath.c_str()); Json::CharReaderBuilder builder; builder["collectComments"] = true; Json::Value root; std::string err; std::ifstream ifs(strPath); if (!ifs.is_open()) { printf("error:file is open\n"); return false; } if (!Json::parseFromStream(builder, ifs, &root, &err)) { printf("error:parseFromStream\n"); return false; } m_TestJC_ImageDate.erase(m_TestJC_ImageDate.begin(), m_TestJC_ImageDate.end()); { auto value = root["img_date"]; if (value.isObject()) { auto arr = value["date"]; std::cout << arr << std::endl; if (arr.isArray()) { // 遍历数组中的每个元素 for (int i = 0; i < arr.size(); i++) { // 读取对象中的属性值 std::string strdata = arr[i].asString(); m_TestJC_ImageDate.push_back(strdata); // 输出属性值 std::cout << "date: " << strdata << std::endl; } } } } // getchar(); return 0; } int deal::InitDetData() { m_read_ImgNum = 0; return 0; } int deal::InsertDetResult(ReadImgInfo tem) { std::lock_guard lock(mtx_List[Mutex_Type_DetResult]); m_DetResultList.push_back(tem); return 0; } int deal::GetUpMaskImg(cv::Mat inImg, cv::Rect roi, cv::Mat &maskimg) { // 定义滑动窗口的大小和步长 int windowWidth = 128; int windowHeight = 128; int stepX = 110; // 横向步长 int stepY = 110; // 纵向步长 maskimg = cv::Mat(roi.height, roi.width, CV_8U, cv::Scalar(0)); int sx = roi.x; int ex = roi.x + roi.width; int sy = roi.y; int ey = roi.y + roi.height; cv::Rect detroi; detroi.width = windowWidth; detroi.height = windowHeight; cv::Rect maskroi; maskroi.width = windowWidth; maskroi.height = windowHeight; cv::Mat temmask; // 遍历图像,使用滑动窗口 for (int y = sy; y <= ey; y += stepY) { detroi.y = y; if (detroi.y + windowHeight > ey) { detroi.y = ey - windowHeight; } maskroi.y = detroi.y - sy; for (int x = sx; x <= ex; x += stepX) { detroi.x = x; if (detroi.x + windowWidth > ex) { detroi.x = ex - windowWidth; } maskroi.x = detroi.x - sx; int thresholdValue = 30; // 初始阈值,OTSU将自动计算 int maxVal = 255; // 最大值 double otsuThreshold; cv::Scalar mean, stddev; cv::meanStdDev(inImg(detroi), mean, stddev); int varianceImg; varianceImg = mean[0] + 1 * mean[0]; if (mean[0] > 100) { continue; } // 使用 OTSU 阈值处理 otsuThreshold = cv::threshold(inImg(detroi), temmask, thresholdValue, maxVal, cv::THRESH_BINARY | cv::THRESH_OTSU); thresholdValue = otsuThreshold; if (thresholdValue < 30) { thresholdValue = 30; } if (thresholdValue < varianceImg) { thresholdValue = varianceImg; } if (thresholdValue > 100) { continue; } // std::cout << "varianceImg value is: " << varianceImg << std::endl; // std::cout << "OTSU threshold value is: " << otsuThreshold << std::endl; // std::cout << "stddev[0] value is: " << stddev[0] << std::endl; otsuThreshold = cv::threshold(inImg(detroi), maskimg(maskroi), thresholdValue, maxVal, cv::THRESH_BINARY); // cv::threshold(inImg(detroi), maskimg(maskroi), thresholdValue, maxVal, cv::THRESH_BINARY + cv::THRESH_OTSU); // 提取当前窗口 // cv::rectangle(inImg, detroi, cv::Scalar(255, 0, 0)); } } // cv::imwrite("inImg1123.png", inImg); // cv::imwrite("maskimg.png", maskimg); // getchar(); return 0; } int deal::SendImgToCheck(std::shared_ptr pDetImageInfo, IN_IMG_Status_ status) { if (pDetImageInfo == nullptr) { return -1; } if (status == IN_IMG_Status_End) { std::shared_ptr tem = std::make_shared(); tem->strImgProductID = pDetImageInfo->strProductID; tem->Status = -1; if (m_pALLImgCheckAnalysisy) { m_pALLImgCheckAnalysisy->SetDataRun_SharePtr(tem); } return 0; } std::shared_ptr tem = std::make_shared(); tem->strChannel = pDetImageInfo->strchannelName; string cur_time = CheckUtil::getCurTimeHMS(); printf("[%s]========SendImgToCheck============ %s \n", cur_time.c_str(), tem->strChannel.c_str()); // cv::imwrite(tem->strChannel+".png",pDetImageInfo->img); tem->nImgBigIdx = 0; tem->strImgName = pDetImageInfo->strName; tem->strImgProductID = pDetImageInfo->strProductID; tem->imgstr = m_strCurDate; tem->strCameraName = pDetImageInfo->strCamID; tem->camera_ID = 0; if (m_nSaveDetprocessImg == 1) { tem->otherValue = 9; } if (pDetImageInfo->img_B.empty()) { tem->bCam_AB = false; } else { tem->bCam_AB = true; tem->img_B = pDetImageInfo->img_B; } tem->getImgTimeMs = getcurTime(); tem->readImg_start = pDetImageInfo->readImg_start; tem->readImg_end = pDetImageInfo->readImg_end; tem->Status = status; tem->Det_Mode = DET_MODE_Det; if ( runConfig.det_Type == RUNTYPE_RUN_Merge_Img) { tem->Det_Mode = DET_MODE_MergeImg; } tem->img = pDetImageInfo->img; if (m_nSaveDetprocessImg == 1) { tem->bsaveProcessImg = true; } if (runConfig.bSaveProcessImg) { tem->bsaveProcessImg = true; } int re = 0; if (m_pALLImgCheckAnalysisy) { re = m_pALLImgCheckAnalysisy->SetDataRun_SharePtr(tem); } return re; } int deal::ReJson() { return 0; } int deal::ReJson_ALL() { printf(">>> ReJson ALL start \n"); // 1、获取所有的json std::vector img_paths; cv::glob(runConfig.filePath + "/*.json", img_paths, true); if (img_paths.size() <= 0) { printf("json file is NULL \n"); return 1; /* code */ } // 用map存储每个id对应的vector std::unordered_map> ProductJsonList; // 遍历路径并按照ID分组 for (const auto &path : img_paths) { // 获取路径中的 ID 部分(即文件夹名部分) size_t start_pos = path.find_last_of("/") + 1; size_t end_pos = path.find("_", start_pos); std::string id = path.substr(start_pos, end_pos - start_pos); // printf("id %s\n",id.c_str()); // 将文件路径加入对应 ID 的vector中 ProductJsonList[id].push_back(path); } for (const auto &product : ProductJsonList) { std::cout << product.first << " => " << product.second.size() << std::endl; std::vector jsonList; std::string strProductName = product.first; for (const auto &str : product.second) { { // 2、获取第一个 名称 std::string strPath = str; size_t lastSlashPos = strPath.find_last_of('/'); // 提取文件名(从最后一个斜杠之后的部分) std::string filename = strPath.substr(lastSlashPos + 1); // 查找文件名中的第一个下划线位置 size_t firstUnderscorePos = filename.find('_'); // 提取文件名中的名称部分(下划线之前的字符串) std::string strProduct = filename.substr(0, firstUnderscorePos); // printf("strProduct %s \n", strProduct.c_str()); if (strProduct == strProductName) { Json_Det_Path tem; tem.strPath_Json = str; tem.strPath_CutImg = str; size_t pos = tem.strPath_CutImg.rfind(".json"); if (pos != std::string::npos) { // 替换 ".json" 为 "_RE_CutImg.png" tem.strPath_CutImg.replace(pos, 5, "_RE_CutImg.png"); } std::cout << " Path: " << tem.strPath_Json << std::endl; std::cout << " Path: " << tem.strPath_CutImg << std::endl; jsonList.push_back(tem); } } } ReJson_product(jsonList, strProductName); } // 获取要检测的 json 图片 list printf(">>>>>>>>>>>>>>>>>>>> rejson ALL is Complete \n"); return 0; } int deal::DetImg() { // 单张检测 if (runConfig.det_Type == RUNTYPE_RUN_Pre || runConfig.det_Type == RUNTYPE_RUN_Merge_Img) { m_nReadThread_type = READ_THREAD_TYPE_READIMG; StartThread(THREAD_RUN_Only_ReadImg); preCheck(); return 0; } if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST || runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { std::string str1 = "/home/aidlux/BOE/Edge/Big/"; _sysmkdirs_1(str1); str1 = "/home/aidlux/BOE/Edge/Result/"; _sysmkdirs_1(str1); str1 = "/home/aidlux/BOE/Edge/Smasll/"; _sysmkdirs_1(str1); m_nReadThread_type = READ_THREAD_TYPE_READIMG; StartThread(THREAD_RUN_Only_ReadImg); Det_Funtion_Test(); return 0; } m_nReadThread_type = READ_THREAD_TYPE_READIMG; // 文件夹套图处理 if (RUNTYPE_RUN_File == runConfig.det_Type) { std::string str = runConfig.filePath; LoadProductID(str); } // getchar(); m_nSystemCheckType = CHECK_TYPE_OFFLING; StartThread(THREAD_RUN_ALL); return 0; } int deal::ReJson_product(std::vector &jsonList, std::string strProductName) { // 获取要检测的 json 图片 list int temstatus = IN_IMG_Status_Start; int PushNum = 0; // 开始逐一复测 for (int i = 0; i < jsonList.size(); i++) { std::string strJson = jsonList.at(i).strPath_Json; std::string strimg = jsonList.at(i).strPath_CutImg; std::ifstream file(strJson); if (!file.is_open()) { std::cerr << "Unable to open file!" << std::endl; return -1; } // 读取文件内容到 std::string std::stringstream buffer; buffer << file.rdbuf(); std::string json_str = buffer.str(); // 获取 JSON 文件的内容作为字符串 // 显示读取到的 JSON 字符串 // std::cout << "JSON content: " << json_str << std::endl; cv::Mat cutimg = cv::imread(strimg, 0); int f0 = strJson.rfind('_'); int f1 = strJson.rfind('.'); int f2 = strJson.rfind('/'); std::string str1 = strJson.substr(f2 + 1, f1 - f2 - 1); std::string str2 = strJson.substr(f0 + 1, f1 - f0 - 1); // std::string str3 = strJson.substr(f2 + 1, strJson.size() - f2); std::cout << str1 << std::endl; std::cout << str2 << std::endl; if (str1.find("CA") != std::string::npos) { str2 = "CA"; } else if (str1.find("TA") != std::string::npos) { str2 = "TA"; } else { continue; } std::cout << "start " << strJson << std::endl; std::shared_ptr result; // 多线程 互斥 作用域 { std::shared_ptr temdet = std::make_shared(); temdet->strCameraName = str2; temdet->strImgProductID = strProductName; temdet->strChannel = str2; temdet->strImgName = str1; std::cout << "strChannel " << temdet->strChannel << std::endl; temdet->Det_Mode = DET_MODE_ReJson; temdet->img = cutimg; temdet->resultJson = json_str; { if (i == 0) { temdet->Status = IN_IMG_Status_Start; } else if (i == jsonList.size() - 1) { temdet->Status = IN_IMG_Status_End; } else { temdet->Status = IN_IMG_Status_Other; } } int re = m_pALLImgCheckAnalysisy->SetDataRun_SharePtr(temdet); if (re != 0) { printf("reJson Error %d \n", re); continue; } PushNum++; // 结果异常 } } int getresultNum = 0; while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费过程 // 处理结果 std::shared_ptr checkResult; int re = m_pALLImgCheckAnalysisy->GetCheckReuslt(checkResult); printf("********************** Get result %d -- %s \n", getresultNum, checkResult->in_shareImage->strChannel.c_str()); saveImg("/home/aidlux/BOE/ReJsonresult/", checkResult); getresultNum++; if (getresultNum == PushNum) { break; } } return 0; } void deal::GetResultThread() { std::vector vi; vi.push_back(18); auto nRet = set_cpu_id(vi); printf("bind cpu ret %d, %d\n", nRet, 18); int re = 0; int nsleep1 = 2 * 1000; while (!m_bExit) { // 1、拷贝检测结果到队列 GetDealResultToQueu(); usleep(nsleep1); } } void deal::ReadImgThread(int id) { int nsleep1 = 200 * 1000; int readThreadIdx = id; while (!m_bExit) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟消费过程 // 读图模式 if (READ_THREAD_TYPE_READIMG == m_nReadThread_type) { Thread_ReadImg(readThreadIdx); } else if (READ_THREAD_Detect == m_nReadThread_type) { } } } void deal::testimg(cv::Mat img) { } int deal::updataResltInfo(std::shared_ptr result) { mutex_DetResult_.lock(); std::string productID = result->in_shareImage->strImgProductID; std::string imgName = result->in_shareImage->strChannel; // printf("add productID %s imgName %s %d\n", productID.c_str(), imgName.c_str(), result->nresult); long t1 = getcurTime(); m_DetResult.updata(productID, imgName, result->nresult, t1); for (int i = 0; i < ERROR_TYPE_COUNT; i++) { if (result->defectResultList[i].nresult == 1) { m_DetResult.update_qx(result->defectResultList[i].keyName, result->defectResultList[i].num); } } mutex_DetResult_.unlock(); return 0; } // 滑动窗口二值化函数 void deal::slidingWindowAutoThreshold(const cv::Mat &src, cv::Mat &dst, int windowSize, int step, double C) { // 确保窗口大小为奇数 // if (windowSize % 2 == 0) // { // windowSize++; // } // 创建目标图像 dst = cv::Mat::zeros(src.size(), CV_8UC1); // 获取源图像的尺寸 int rows = src.rows; int cols = src.cols; int xs = 0; int xe = windowSize; int ys = 0; int ye = windowSize; for (int y = ye; y < rows;) { int xs = 0; int xe = windowSize; for (int x = xe; x < cols;) { cv::Rect roi; roi.x = xs; roi.width = windowSize; roi.y = ys; roi.height = windowSize; cv::Mat window = src(roi); // 计算窗口中的平均值和标准差 cv::Scalar mean, stdDev; cv::meanStdDev(window, mean, stdDev); // printf(" x %d %d y %d %d %f %f \n", xs, xe, ys, ye, mean[0], stdDev[0]); int T = mean[0] + 20 * stdDev[0]; cv::threshold(window, dst(roi), T, 255, cv::THRESH_BINARY); // cv::rectangle(src, roi, cv::Scalar(255, 0, 255)); if (xe == cols) { break; } xs = xs + step; xe = xs + windowSize; if (xs < cols && xe > cols) { xe = cols; xs = xe - windowSize; } } if (ye == rows) { break; } ys = ys + step; ye = ys + windowSize; if (ys < rows && ye > rows) { ye = rows; ys = ye - windowSize; } } // // 遍历图像的每个像素 // for (int i = 0; i < rows; ++i) // { // for (int j = 0; j < cols; ++j) // { // // 计算窗口边界 // int startRow = std::max(0, i - windowSize / 2); // int endRow = std::min(rows - 1, i + windowSize / 2); // int startCol = std::max(0, j - windowSize / 2); // int endCol = std::min(cols - 1, j + windowSize / 2); // // 提取窗口中的图像块 // cv::Mat window = src(cv::Range(startRow, endRow + 1), cv::Range(startCol, endCol + 1)); // // 计算窗口中的平均值和标准差 // cv::Scalar mean, stdDev; // cv::meanStdDev(window, mean, stdDev); // // 计算局部阈值 // double threshold = mean[0] - C * stdDev[0]; // // 根据局部阈值进行二值化 // if (src.at(i, j) >= threshold) // { // dst.at(i, j) = 255; // } // else // { // dst.at(i, j) = 0; // } // } // } } int deal::testimgUP(cv::Mat img) { cv::Mat dst; slidingWindowAutoThreshold(img, dst, 200, 180, 10); cv::imwrite("up_dst.png", dst); cv::imwrite("up.png", img); printf("1111\n"); getchar(); return 0; } int deal::test_ZF(ReadImgInfo tem, int id) { std::string ressss = "**"; for (int i = 0; i < id; i++) { ressss += "*******"; } // printf("%s %d start redimg img idx %d ID %s ch %s tem.imglist %zu\n ", ressss.c_str(), id, tem.idx, tem.strImgSN.c_str(), tem.strChannel.c_str(), tem.imglist.size()); long t1 = getcurTime(); cv::Mat L255Img = cv::imread(tem.strPath, 0); long t2 = getcurTime(); mtx_DetImgQueue_com.lock(); m_read_ImgNum++; long useTime = t2 - m_readImgStarttime; // printf("read Img mean time %ld -- m_read_ImgNum %d use time %ld \n", useTime / m_read_ImgNum, m_read_ImgNum, useTime / 1000); mtx_DetImgQueue_com.unlock(); printf("---------------------ThreadID %d readimg %d / %d use time %ld %s \n", id, tem.idx, tem.sumNUm, t2 - t1, tem.strPath.c_str()); // printf("tem.strPath %s *\n", tem.strPath.c_str()); // printf("%s %d End redimg use time %ld \n ", ressss.c_str(), id, t2 - t1); cv::Mat mask; if (L255Img.empty()) { printf("error:No L255 Img -------------- \n"); InsertDetResult(tem); return 1; } tem.status = 1; int re = 0; std::shared_ptr result; // 多线程 互斥 作用域 // if (false) { std::lock_guard lock(mtx_DetImgQueue_edge); { if (tem.strChannel == "L255") { std::shared_ptr temdet = std::make_shared(); if (m_nSaveDetprocessImg == 1) { temdet->otherValue = 9; } temdet->strImgName = "test"; temdet->strImgProductID = tem.strImgSN; temdet->strChannel = tem.strChannel; // if (m_nReadThread_type == READ_THREAD_TYPE_EDGE) { temdet->Det_Mode = DET_MODE_EDGE; if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { temdet->ninstruct = 999; } } temdet->img = L255Img; printf(">>>>>>>>>>>m_nReadThread_type %d runConfig.det_Type %d temdet->ninstruct %d >>>>>>>>> ThreadID %d start Check readimg %d / %d ID %s ch %s \n ", m_nReadThread_type, runConfig.det_Type, temdet->ninstruct, id, tem.idx, tem.sumNUm, tem.strImgSN.c_str(), tem.strChannel.c_str()); m_pALLImgCheckAnalysisy->CheckImg(temdet, result); // 结果异常 if (result->nresult != 0) { printf("preCheck Img edge error..... %s \n", tem.strPath.c_str()); InsertDetResult(tem); return ERROR_PRECHECK_IMG_NULL; } tem.status = 2; InsertDetResult(tem); } } } return 0; } int deal::SetStatus(int type, int status) { std::lock_guard lock(mtx_List[Mutex_Type_DetStatus]); m_DetStatusList[type] = status; return 0; } int deal::GetStatus(int type) { std::lock_guard lock(mtx_List[Mutex_Type_DetStatus]); return m_DetStatusList[type]; } bool deal::IsStatus(int type, int status) { std::lock_guard lock(mtx_List[Mutex_Type_DetStatus]); if (m_DetStatusList[type] == status) { return true; } return false; } int deal::SetStatus_List(int idx, Thread_Status_ status) { std::lock_guard lock(mtx_List[Mutex_Type_ReadImgThread]); m_nReadStausList[idx] = status; return 0; } int deal::GetStatus_List(int idx) { std::lock_guard lock(mtx_List[Mutex_Type_ReadImgThread]); return m_nReadStausList[idx]; } bool deal::IsStatus_List(int idx, Thread_Status_ status) { std::lock_guard lock(mtx_List[Mutex_Type_ReadImgThread]); if (idx < 0 || idx >= READ_IMG_THREAD_NUM) { } else { if (m_nReadStausList[idx] == status) { return true; } } return false; } int deal::setReadThreadStart() { for (int i = 0; i < READ_IMG_THREAD_NUM; i++) { SetStatus_List(i, Thread_Status_READY); } return 0; } int deal::GetReadImgCompleteThreadIdx() { for (int i = 0; i < READ_IMG_THREAD_NUM; i++) { if (IsStatus_List(i, Thread_Status_COMMPLET)) { return i; } } return -1; } bool deal::IsALLComplete() { std::lock_guard lock(mtx_List[Mutex_Type_DetStatus]); for (size_t i = 0; i < READ_IMG_THREAD_NUM; i++) { if (m_nReadStausList[i] == ReadImg_Status_COMMPLET) { return false; } } return true; } int deal::InitCPUIDX() { int start = 3; m_CPUInfo[THREAD_CPU_Main_Det].set(start, 4); start += 4; m_CPUInfo[THREAD_CPU_Main_readImg].set(start, READ_IMG_THREAD_NUM); start += READ_IMG_THREAD_NUM; m_CPUInfo[THREAD_CPU_Main_saveImg].set(start, Save_IMG_THREAD_NUM); start += Save_IMG_THREAD_NUM; m_CPUInfo[THREAD_CPU_CheckSo].set(start, 15); return 0; } void deal::Thread_ReadImg(int id) { if (!IsStatus_List(id, Thread_Status_READY)) { return; } int re = 0; std::shared_ptr pImageInfo = nullptr; re = GetReadImgInfo(pImageInfo); if (pImageInfo == nullptr) { printf("pImageInfo == nullptr=================id %d=============\n", id); return; } // pImageInfo->img = cv::imread(pImageInfo->strPath, 0); m_pextractImg->ReadCELLImg(pImageInfo->strPath, pImageInfo->img, runConfig.bdecode); // cv::imwrite(pImageInfo->strchannelName + "_A_ssssde.png", pImageInfo->img); if (pImageInfo->strPath_B != "") { m_pextractImg->ReadCELLImg(pImageInfo->strPath_B, pImageInfo->img_B, runConfig.bdecode); // cv::imwrite(pImageInfo->strchannelName + "_B_sssde.png", pImageInfo->img_B); } m_ReadImgThread_Result[id] = pImageInfo; // 线程完成读图,设置现场状态为 完成 SetStatus_List(id, Thread_Status_COMMPLET); // printf("Thread_ReadImg=================id %d %s=============\n", id, pImageInfo->strPath.c_str()); } int deal::InsertReadImgInfo(std::shared_ptr pImageInfo) { std::lock_guard lock(mutex_ReadImgList); m_ReadImg_queue.push(pImageInfo); cv_ReadImgList.notify_one(); // 唤醒等待的线程 return 0; } int deal::GetReadImgInfo(std::shared_ptr &pImageInfo) { // printf("===============waite img info ===============\n"); std::unique_lock lock(mutex_ReadImgList); cv_ReadImgList.wait(lock, [this]() { return !m_ReadImg_queue.empty(); }); pImageInfo = m_ReadImg_queue.front(); // 获取队首数据 if (pImageInfo == NULL) { return 1; } m_ReadImg_queue.pop(); // 弹出队首数据 return 0; } int deal::LoadOfflineCheckImg(std::string strImgPath) { std::vector img_paths; cv::glob(strImgPath, img_paths, true); m_OffLineCheckImgList.erase(m_OffLineCheckImgList.begin(), m_OffLineCheckImgList.end()); m_OffLineCheckImgNameList.erase(m_OffLineCheckImgNameList.begin(), m_OffLineCheckImgNameList.end()); for (int i = 0; i < img_paths.size(); i++) { size_t found = img_paths[i].find_last_of("/\\"); // std::cout << img_paths[i] << std::endl; std::string str = img_paths[i]; m_OffLineCheckImgNameList.push_back(str); } return 0; } int deal::LoadImgPath_JCSN(std::string strImgPath) { std::cout << strImgPath << std::endl; std::vector img_paths; cv::glob(strImgPath, img_paths, true); m_OffImageSNPathList.erase(m_OffImageSNPathList.begin(), m_OffImageSNPathList.end()); for (int i = 0; i < img_paths.size(); i++) { std::string path = img_paths[i]; // std::cout << img_paths[i] << std::endl; // 提取所有文件夹名称 std::vector allDirectories = extractAllDirectories(path); std::string strSN = ""; // 输出所有文件夹名称 std::string strAllPath = "/"; for (const auto &dir : allDirectories) { strAllPath += dir; if (isValidString(dir)) { strSN = dir; // std::cout << strSN << std::endl; break; } strAllPath += "/"; } bool bh = false; for (int j = 0; j < m_OffImageSNPathList.size(); j++) { if (m_OffImageSNPathList.at(j) == strAllPath) { bh = true; break; } } if (!bh) { if (m_OffImageSNPathList.size() < m_nTestNum) { m_OffImageSNPathList.push_back(strAllPath); std::cout << strAllPath << std::endl; } // std::cout << strSN << std::endl; } } return 0; } bool deal::isValidString(const std::string &str) { // 检查字符串长度是否为10 if (str.length() < 14 || str.length() > 19) { return false; } // 检查字符串中的每个字符是否都是字母或数字 for (char c : str) { if (!std::isalnum(c)) { // 如果字符不是字母或数字 return false; } } // 字符串满足条件 return true; } int deal::LoadProductID(std::string strImgPath) { m_product_ID_List.erase(m_product_ID_List.begin(), m_product_ID_List.end()); std::vector img_paths; // tif 格式 { std::string str_bmp = strImgPath + "/*.ytimage"; if(!runConfig.bdecode) { str_bmp = strImgPath + "/*.jpg"; } std::cout << str_bmp << std::endl; cv::glob(str_bmp, img_paths, true); for (int i = 0; i < img_paths.size(); i++) { std::string path = img_paths[i]; // 提取所有文件夹名称 std::vector allDirectories = extractAllDirectories(path); std::string strSN = ""; // 输出所有文件夹名称 std::string strAllPath = "/"; for (const auto &dir : allDirectories) { // std::cout << dir << std::endl; strAllPath += dir; if (isValidString(dir)) { strSN = dir; break; } strAllPath += "/"; } bool bh = false; for (int j = 0; j < m_product_ID_List.size(); j++) { if (m_product_ID_List.at(j) == strAllPath) { bh = true; break; } } if (!bh) { if (m_product_ID_List.size() < m_nTestNum) { m_product_ID_List.push_back(strAllPath); std::cout << strAllPath << std::endl; } } } } return 0; } int deal::DelImg_Cell_ET() { size_t totalSize = m_product_ID_List.size(); if (totalSize > 0) { m_DetResult.Init(); /* code */ } for (size_t idx = 0; idx < totalSize; idx++) { string cur_time = CheckUtil::getCurTimeHMS(); printf("[%s]>>> %zu / %zu %s----start \n", cur_time.c_str(), idx, totalSize, m_product_ID_List.at(idx).c_str()); long t1, t2; t1 = getcurTime(); Det_OneProduct_Cell_ET(m_product_ID_List.at(idx), idx); t2 = getcurTime(); string cur_time_end = CheckUtil::getCurTimeHMS(); printf("[%s]>>> %zu / %zu %s----End use time %ld\n", cur_time_end.c_str(), idx, totalSize, m_product_ID_List.at(idx).c_str(), t2 - t1); } if (totalSize > 0) { // 等待所有检测都完成 while (true) { usleep(1000 * 1000 * 10); printf("len %zu \n", m_Result_list.size()); if (m_Result_list.size() <= 0) { printf("check =============== complete \n"); break; } } } m_product_ID_List.erase(m_product_ID_List.begin(), m_product_ID_List.end()); m_product_ID_List.clear(); return RESULT_OK; } int deal::Det_OneProduct_Cell_ET(std::string strProductName, int Idx) { std::string strProductID = GetFileName(strProductName); // 获取图片路径 std::vector detImgInfoList; string strSearchImg = strProductName; int re = GetDetImageInfo(strProductID, strSearchImg, detImgInfoList); if (re != 0) { return re; } // 没有图片 if (detImgInfoList.size() <= 0) { return 1; } // 读图现场都开启 setReadThreadStart(); int AllImgNum = detImgInfoList.size(); // 遍历所有图片 开始读图处理 for (int i = 0; i < detImgInfoList.size(); i++) { std::shared_ptr tem = std::make_shared(); tem->copy(detImgInfoList.at(i)); InsertReadImgInfo(tem); } m_DetResult.startTime_S = getcurTime(); IN_IMG_Status_ temstatus = IN_IMG_Status_Start; std::shared_ptr tempDetImageInfo = nullptr; Det_One_Result_Info tem_one; tem_one.Product_ID = strProductID; tem_one.result = 0; long ts = getcurTime(); tem_one.time_s = ts; int GetImgNum = 0; while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟消费过程 int ThreadIdx = GetReadImgCompleteThreadIdx(); if (ThreadIdx < 0) { continue; } std::shared_ptr pDetImageInfo = nullptr; pDetImageInfo = m_ReadImgThread_Result[ThreadIdx]; // 开始送到检测进行处理 if (pDetImageInfo != nullptr) { // printf(">>> %s----start \n", pDetImageInfo->strName.c_str()); tempDetImageInfo = pDetImageInfo; int re = SendImgToCheck(pDetImageInfo, temstatus); if (re != 0) { continue; } Det_single_img_Result_Info tem_single; tem_single.name = pDetImageInfo->strchannelName; tem_single.result = -1; tem_one.img_result_list.push_back(tem_single); } SetStatus_List(ThreadIdx, Thread_Status_READY); GetImgNum++; if (IN_IMG_Status_Start == temstatus) { temstatus = IN_IMG_Status_Other; } // 图是否都读取完了。 bool bReadCompleted = false; if (GetImgNum >= AllImgNum) { bReadCompleted = true; } // 退出 if (bReadCompleted) { SendImgToCheck(tempDetImageInfo, IN_IMG_Status_End); break; } } m_DetResult.one_result_list.push_back(tem_one); m_DetResult.det_num_all++; // if (m_DetResult.det_num_all == 1) // { // } // printf("startTime_S==== %ld \n", m_DetResult.startTime_S); // getchar(); return 0; } int deal::Det_Edge_Test_OneImg() { int imgNum = 0; std::string strchannel = "L255"; std::string str = runConfig.filePath + "/*" + strchannel + ".tif"; { std::cout << str << std::endl; m_OffImageSNPathList.erase(m_OffImageSNPathList.begin(), m_OffImageSNPathList.end()); cv::glob(str, m_OffImageSNPathList, true); } imgNum = m_OffImageSNPathList.size(); if (imgNum > m_nTestNum && m_nTestNum > 0) { imgNum = m_nTestNum; } printf("Img Num %d \n", imgNum); if (imgNum <= 0) { return 0; } for (int i = 0; i < m_OffImageSNPathList.size(); i++) { printf(">>> %d / %zu --start \n", i, m_OffImageSNPathList.size()); long t1, t2; cv::Mat detimg = cv::imread(m_OffImageSNPathList.at(i)); { std::shared_ptr result; std::shared_ptr temdet = std::make_shared(); if (m_nSaveDetprocessImg == 1) { temdet->otherValue = 9; } temdet->strImgName = "test"; temdet->strImgProductID = "test"; temdet->strChannel = "L255"; if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST || runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { temdet->Det_Mode = DET_MODE_EDGE; if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { temdet->ninstruct = 999; } } temdet->img = detimg; m_pALLImgCheckAnalysisy->CheckImg(temdet, result); // 结果异常 } } return 0; } int deal::Det_Funtion_Test() { int re = 0; if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST || runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { Det_Funtion_Edge(); return 0; } // 获取图片 return 0; } int deal::Det_Funtion_Edge() { int imgNum = 0; std::string strchannel = "L255"; std::string str = runConfig.filePath + "/*" + strchannel + ".tif"; { std::cout << str << std::endl; m_OffImageSNPathList.erase(m_OffImageSNPathList.begin(), m_OffImageSNPathList.end()); cv::glob(str, m_OffImageSNPathList, true); } imgNum = m_OffImageSNPathList.size(); if (imgNum > m_nTestNum && m_nTestNum > 0) { imgNum = m_nTestNum; } printf("Img Num %d \n", imgNum); if (imgNum <= 0) { return 0; } // 读图现场都开启 setReadThreadStart(); int AllImgNum = imgNum; // 遍历所有图片 开始读图处理 for (int i = 0; i < imgNum; i++) { std::shared_ptr tem = std::make_shared(); tem->strPath = m_OffImageSNPathList.at(i); tem->strchannelName = strchannel; InsertReadImgInfo(tem); } int GetImgNum = 0; while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟消费过程 int ThreadIdx = GetReadImgCompleteThreadIdx(); if (ThreadIdx < 0) { continue; } std::shared_ptr pDetImageInfo = nullptr; pDetImageInfo = m_ReadImgThread_Result[ThreadIdx]; SetStatus_List(ThreadIdx, Thread_Status_READY); GetImgNum++; // 开始送到检测进行处理 if (pDetImageInfo == nullptr) { continue; } // printf("GetImgNum:111111111111111 %d\n", GetImgNum); { std::shared_ptr result; std::shared_ptr temdet = std::make_shared(); if (m_nSaveDetprocessImg == 1) { temdet->otherValue = 9; } temdet->strImgName = "test"; temdet->strImgProductID = "test"; temdet->strChannel = strchannel; if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST || runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { temdet->Det_Mode = DET_MODE_EDGE; if (runConfig.det_Type == RUNTYPE_RUN_EDGE_TEST_AI) { temdet->ninstruct = 999; } } temdet->img = pDetImageInfo->img; m_pALLImgCheckAnalysisy->CheckImg(temdet, result); // 结果异常 } // 图是否都读取完了。 if (GetImgNum >= AllImgNum) { break; } } return 0; } int deal::RandDrawImg(cv::Mat srcimg, cv::Mat &randErrorImg) { randErrorImg = srcimg.clone(); cv::Rect roi; roi.x = (rand() % (srcimg.cols - 20 - 20)) + 20; roi.y = (rand() % (srcimg.rows - 20 - 20)) + 20; roi.width = (rand() % (100 - 5)) + 5; roi.height = roi.width; if (roi.x + roi.width >= srcimg.cols) { roi.x = srcimg.cols - roi.width - 1; /* code */ } if (roi.y + roi.height >= srcimg.rows) { roi.y = srcimg.rows - roi.height - 1; /* code */ } randErrorImg(roi).setTo(30); return 0; } void deal::DealImg() { // 线程送图处理: std::vector vi; int startidx = m_CPUInfo[THREAD_CPU_Main_Det].startIdx; int cpunum = m_CPUInfo[THREAD_CPU_Main_Det].num; for (int i = 0; i < cpunum; i++) { vi.push_back(startidx + i); } auto nRet = set_cpu_id(vi); printf("THREAD_CPU_Main_Det bind cpu ret %d startidx %d num %d\n", nRet, startidx, cpunum); int re = 0; while (!m_bExit) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费过程 re = DelImg_Cell_ET(); } } // 提取所有文件夹名称函数 std::vector deal::extractAllDirectories(const std::string &path) { std::vector directories; std::string directory; // 遍历路径中的每个字符 for (char c : path) { // 如果遇到路径分隔符,则将当前文件夹名称存储起来 if (c == '/' || c == '\\') { if (!directory.empty()) { // 确保文件夹名称不为空 directories.push_back(directory); directory.clear(); // 清空当前文件夹名称 } } else { directory += c; // 将字符添加到当前文件夹名称中 } } // 将最后一个文件夹名称添加到列表中 if (!directory.empty()) { directories.push_back(directory); } return directories; }