/* * @Author: xiewenji 527774126@qq.com * @Date: 2025-09-23 18:06:58 * @LastEditors: xiewenji 527774126@qq.com * @LastEditTime: 2025-09-26 10:10:28 * @FilePath: /BOE_POL_ET_Detect/AlgorithmModule/src/CameraCheckAnalysisy.cpp * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ /* * @Author: your name * @Date: 2022-04-20 15:50:00 * @LastEditTime: 2025-09-25 18:03:34 * @LastEditors: xiewenji 527774126@qq.com * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @FilePath: /ZCXD_MonitorPlatform/src/CoreLogicModule/src/CamDeal.cpp */ #include "CameraCheckAnalysisy.hpp" #include "CheckUtil.hpp" #include "Define.h" #include #include #include #include #include #include #include #include static std::mutex g_ngImgSave_mutex; static std::vector> g_ngImgSave_futures; CameraCheckAnalysisy::CameraCheckAnalysisy() { m_nErrorCode = 0; // 错误代码 m_bInitSucc = false; // 初始化状态 m_bExit = false; // 是否退出检测 m_bHaveImgeDet = false; m_strcameraName = ""; nLastCheckAnalysisyThreadIdx = 0; m_pChannelFuntion = &m_AnalysisyConfig.checkFunction; m_pbaseCheckFunction = &m_AnalysisyConfig.baseFunction; m_nConfigIdx = -1; m_pdetlog = std::make_shared(); m_pCommonAnalysisyConfig = NULL; m_imageResultJudge.SetAnalysisyConfig(&m_AnalysisyConfig); m_strRootPath_MergeImg = "/home/aidlux/BOE/FOG/MergeImg/"; CheckUtil::CreateDir(m_strRootPath_MergeImg); // m_pQX_Merge_Analysis = QX_Merge_Analysis::GetInstance(); } CameraCheckAnalysisy::~CameraCheckAnalysisy() { } int CameraCheckAnalysisy::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; } int CameraCheckAnalysisy::WaitDetImg() { std::unique_lock lk(mtx_WaiteImg); cond_WaiteImg.wait(lk, [this]() { return m_bHaveImgeDet; }); lk.unlock(); return 0; } int CameraCheckAnalysisy::Detect_Pre() { //==========解密图片 long ts = CheckUtil::getcurTime(); std::string strlog; std::string strSN; std::string strBasic; strSN = m_pCheck_Result->productBaseResult->strproductName; strBasic = ">>" + strSN + " cam:" + m_strcameraName; m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s ==================start", strBasic.c_str()); // printf( "%s ==================Detect_Pre start\n", strBasic.c_str()); std::shared_ptr L255 = m_pCheck_Result->GetL255DetImg(); if (L255 == NULL || L255->result->in_shareImage->img.empty()) { if (L255 && L255->result->in_shareImage->img.empty()) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --L255 Img is empty ", strBasic.c_str()); } else { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --L255 NULL ", strBasic.c_str()); } return 1; } ChannelCheckFunction *pFuntion_L255 = GetChannelFuntion("L255"); if (!pFuntion_L255) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --L255 function is error ", strBasic.c_str()); return 1; } // 用L255 检测图片边缘 int re = ImgEdge(L255, pFuntion_L255); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --ImgEdge error ", strBasic.c_str()); return 1; } if (m_pCheck_Result->cameraBaseResult->pEdgeDetResult->nresult != 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --ImgEdge result error = %d ", strBasic.c_str(), m_pCheck_Result->cameraBaseResult->pEdgeDetResult->nresult); return 1; } // 如果是 边缘检测模式,则停止后面检测,直接退出 if (L255->result->in_shareImage->Det_Mode == DET_MODE_EDGE) { return 9; } cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi; if (!CheckUtil::RoiInImg(Det_CropRoi, L255->result->in_shareImage->img)) { return 0; } cv::Mat L255CutImg = L255->result->in_shareImage->img(Det_CropRoi).clone(); re = Det_MarkLine(L255CutImg, L255, &m_pbaseCheckFunction->markLine); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --Det_MarkLine error ", strBasic.c_str()); } if (DET_MODE_MarkLine == L255->result->in_shareImage->Det_Mode) { return 1; } re = preDet_ZF(L255CutImg, L255); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --preDet_ZF error ", strBasic.c_str()); } if (DET_MODE_ZF == L255->result->in_shareImage->Det_Mode) { return 1; } long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, "Detect_Pre", "==================End time %ld ms ", te - ts); re = preDet_BQ(L255CutImg, L255); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Pre", "%s --preDet_BQ error ", strBasic.c_str()); } // getchar(); // return 1; // printf("Cam image channle %s ==================send start \n", pL255ImageResult->strChannel.c_str()); // getchar(); return 0; } // 对该相机下的每一张图片进行处理 int CameraCheckAnalysisy::Detect_Images() { std::string strlog; std::string strSN; std::string strBasic; strSN = m_pCheck_Result->productBaseResult->strproductName; strBasic = ">>" + strSN + " cam:" + m_strcameraName; m_pdetlog->AddCheckstr(PrintLevel_0, "Detect_Images", "Cam %s ==================start", strBasic.c_str()); // // 循环处理每个图片 bool bcomplete = false; long time_No_CheckAnalysisy = 30 * 1000; long ts = CheckUtil::getcurTime(); while (!bcomplete) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); ImgCheckBase *pImgCheckAnalysisy = NULL; long t1 = CheckUtil::getcurTime(); // 拿到计算资源 while (true) { pImgCheckAnalysisy = GetDealResult(-1); if (pImgCheckAnalysisy != NULL) { break; } std::this_thread::sleep_for(std::chrono::milliseconds(20)); // long t2 = CheckUtil::getcurTime(); // 如果 超过秒XX都没有拿到处理资源,则直接退出 if (t2 - t1 > time_No_CheckAnalysisy) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Images", "Error %ld ms No pImgCheckAnalysisy", time_No_CheckAnalysisy); break; } } // 没有分析检测资源,直接退出 if (pImgCheckAnalysisy == NULL) { continue; } UpdateConfigStatus(); // 1、把每张图都进行AI 推理 获得 blob 结果 std::shared_ptr pImageResult = m_pCheck_Result->GetNoDetImg(); bool bHaveNotdetImg = false; // 没有未检测的图片了。 if (pImageResult) { m_pdetlog->AddCheckstr(PrintLevel_1, "Detect_Images", "strSN %s channel %s send det %s", strSN.c_str(), pImageResult->strChannel.c_str(), CheckUtil::getCurTimeHMS().c_str()); bHaveNotdetImg = true; { pImgCheckAnalysisy->SetDataRun_SharePtr(pImageResult); } } else { // printf("Cam Detect_Images %s =======nnnnnnnnnnnnnnnnnnnnnnnnnnn===========send end \n", strBasic.c_str()); // 图片都已经送完了。 if (m_pCheck_Result->getImgPushComplate()) { // printf("Cam Detect_Images %s ===========PushComplate=======send end \n", strBasic.c_str()); // 没有图在进行 检测了。 bool bhavedet = false; for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++) { if (CHECK_THREAD_STATUS_IDLE != m_pImgCheckAnalysisy[i]->GetStatus()) { bhavedet = true; break; } } // printf("Cam Detect_Images %s ==================bhavedet %d\n", strBasic.c_str(), bhavedet); if (!bhavedet) { bcomplete = true; } } else { // printf("Cam Detect_Images %s ==================No send end\n", strBasic.c_str()); } } } long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, "Detect_Images", "Cam %s =====ALL image det complate time %ld ms=============End", strBasic.c_str(), te - ts); // getchar(); // printf("Cam %s =====ALL image det complate time %ld ms=============End \n", strBasic.c_str(), te - ts); return 0; } int CameraCheckAnalysisy::ResultParamJudge() { //================================================== //======= 适用于 单相机或多相机,每个相机之间的图相互没关系。 //======= //======= //======= //================================================== std::string strSN; std::string strBasic; strSN = m_pCheck_Result->productBaseResult->strproductName; strBasic = ">>" + strSN + " cam:" + m_strcameraName; m_pdetlog->AddCheckstr(PrintLevel_0, "ResultParamJudge", "Cam %s ==================start", strBasic.c_str()); std::string strlog; long ts = CheckUtil::getcurTime(); int ImageNum = m_pCheck_Result->ImageALLDetResultList.size(); if (ImageNum <= 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "Error ImageNum <=0"); return 1; } // 如果 参数是空,直接返回。 if (m_pCommonAnalysisyConfig == NULL) { m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "Error m_pCommonAnalysisyConfig == NULL"); return 1; } int regionNum = m_pCommonAnalysisyConfig->regionConfigArr.size(); if (regionNum <= 0) { m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "Error Config region num = 0"); } m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "==================start image Num %d region num %d %s", ImageNum, regionNum, CheckUtil::getCurTimeHMS().c_str()); m_pQX_Merge_Analysis = m_pCheck_Result->productBaseResult->pQX_Merge_Analysis; m_pQX_Merge_Analysis->SetbaseCheckFunction(m_strcameraName, m_pChannelFuntion, m_pbaseCheckFunction); m_pQX_Merge_Analysis->setSendStatus(m_strcameraName, QX_Merge_Analysis::RUN_STATUS_NULL); m_imageResultJudge.UpdateMergedet(m_pCheck_Result); // 对每个图片通道进行单独分析 for (int imgidx = 0; imgidx < ImageNum; imgidx++) { long t1 = CheckUtil::getcurTime(); int re = m_imageResultJudge.ResultJudge(m_pCheck_Result->ImageALLDetResultList.at(imgidx)); long t2 = CheckUtil::getcurTime(); } m_pQX_Merge_Analysis->setSendStatus(m_strcameraName, QX_Merge_Analysis::RUN_STATUS_READY); m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "===============QX_Merge_Analysis===start %s", CheckUtil::getCurTimeHMS().c_str()); // 等待所有 个数 和距离的分析完成。 m_pQX_Merge_Analysis->waitComplete(); for (auto log : m_pQX_Merge_Analysis->m_pMergedetlog->logList) { m_pdetlog->logList.push_back(log); } QX_Analysis_Result_List *ptemre; m_pQX_Merge_Analysis->GetReusult(ptemre); m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "===============QX_Merge_Analysis===end %s", CheckUtil::getCurTimeHMS().c_str()); // 对每个图片通道进行单独分析 for (int imgidx = 0; imgidx < ImageNum; imgidx++) { long t1 = CheckUtil::getcurTime(); int re = m_imageResultJudge.MergeResult(m_pCheck_Result->ImageALLDetResultList.at(imgidx), ptemre); long t2 = CheckUtil::getcurTime(); #ifdef AI_Time m_imageResultJudge.DrawResult(m_pCheck_Result->ImageALLDetResultList.at(imgidx)); #endif long t3 = CheckUtil::getcurTime(); // m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", " det time %ld ms judge %ld draw %ld", t3 - t1, t2 - t1, t3 - t2); // 把结果转成 json 保存。 用以复测 // std::shared_ptr m_CheckResult_shareP = m_pCheck_Result->ImageALLDetResultList.at(imgidx)->result; // m_CheckResult_shareP->strResultJson = m_CheckResultJson.GetResultString(m_pCheck_Result->ImageALLDetResultList.at(imgidx)->pDetResult); } long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, "ResultParamJudge", "==================End time %ld ms ", te - ts); // m_pdetlog->printLog(m_strcameraName); return 0; } int CameraCheckAnalysisy::MergeResultAnalysisy() { return 0; } int CameraCheckAnalysisy::UpdateConfigStatus() { std::string strBasic; for (int i = 0; i < m_pCheck_Result->ImageALLDetResultList.size(); i++) { std::shared_ptr pImageResult = m_pCheck_Result->ImageALLDetResultList.at(i); if (pImageResult->config_update.bUpdate) { continue; } std::string strChannel = m_pCheck_Result->ImageALLDetResultList.at(i)->strChannel; ChannelCheckFunction *pFuntion = GetChannelFuntion(strChannel); if (pFuntion != NULL) { pImageResult->config_update.wait_UP = pFuntion->function.f_UseUpQX.bOpen; } bool bUseDpResult = false; if (pFuntion != NULL) { // 亮点检测 开启 if (pFuntion->function.f_LDConfig.bOpen) { // 需要dp bUseDpResult = pFuntion->function.f_LDConfig.bUseDP; } if (pFuntion->function.f_AIQX.bPOLToWhitePOL && pFuntion->function.f_AIQX.b127WhitePOl_UseDP) { bUseDpResult = true; } } pImageResult->config_update.wait_DP = bUseDpResult; pImageResult->config_update.bUpdate = true; m_pdetlog->AddCheckstr(PrintLevel_2, "config_update", " %s wait_UP %d wait_DP %d", pImageResult->strBaseInfo.c_str(), pImageResult->config_update.wait_UP, pImageResult->config_update.wait_DP); } return 0; } int CameraCheckAnalysisy::ResultParamJudge_New() { return 0; } int CameraCheckAnalysisy::ImgEdge(std::shared_ptr L255, ChannelCheckFunction *pFuntion_L255) { long ts = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, "ImgEdge", "==================start %s ", m_strcameraName.c_str()); Function_EdgeROI *pEdgeROI; pEdgeROI = &pFuntion_L255->function.f_EdgeROI; // pEdgeROI->print("pEdgeROI"); Function_Image_Align *pAlign; pAlign = &pFuntion_L255->function.f_Image_Align; Edge_Search::DetConfigResult detConfigResult; detConfigResult.pEdgeROI = pEdgeROI; detConfigResult.pAlign = pAlign; detConfigResult.strCamName = m_strcameraName; detConfigResult.pdetlog = m_pdetlog; if (L255->result->in_shareImage->Det_Mode == DET_MODE_EDGE) { detConfigResult.bMode_Edge_test = true; } detConfigResult.bDebugsaveImg = L255->result->in_shareImage->bDebugsaveImg; m_pCheck_Result->cameraBaseResult->pEdgeDetResult = std::make_shared(); int re = m_Edge_Search.Detect(L255->result->in_shareImage->img, &detConfigResult, m_pCheck_Result->cameraBaseResult->pEdgeDetResult); long te = CheckUtil::getcurTime(); if (!m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask_Src.empty()) { cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(40, 40)); // 对掩膜图像进行膨胀 cv::dilate(m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask_Src, m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask_Src, kernel); cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi; if (CheckUtil::RoiInImg(Det_CropRoi, m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask_Src)) { m_pCheck_Result->cameraBaseResult->pEdgeDetResult->edge_cutMask = ~m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask_Src(Det_CropRoi).clone(); if (L255->result->in_shareImage->bDebugsaveImg) { cv::imwrite("edge_cutMask.png", m_pCheck_Result->cameraBaseResult->pEdgeDetResult->edge_cutMask); cv::imwrite("edge_shieldMask_Src.png", m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask_Src); } } } m_pdetlog->AddCheckstr(PrintLevel_1, "ImgEdge", "==================End re = %d time %ld ms edge qx roi %ld ", re, te - ts, m_pCheck_Result->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList->size()); // getchar(); return re; } int CameraCheckAnalysisy::Det_MarkLine(const cv::Mat &L255CutImg, std::shared_ptr L255, Base_Function_MarkLine *pFuntion) { m_pCheck_Result->cameraBaseResult->pMarkLineResult = std::make_shared(); if (pFuntion && !pFuntion->bOpen) { m_pdetlog->AddCheckstr(PrintLevel_1, "Det_MarkLine", "Error pFuntion == NULL or bOpen == false"); return 0; } std::shared_ptr pMarkLineResult = m_pCheck_Result->cameraBaseResult->pMarkLineResult; // MarkLine检测结果 cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi; AI_Mark_Det::DetConfigResult detresult; detresult.strCamName = m_strcameraName; detresult.searchroi = pFuntion->searchRoi; detresult.bDebugsaveimg = L255->result->in_shareImage->bDebugsaveImg; detresult.pdetlog = m_pdetlog; if (DET_MODE_MarkLine == L255->result->in_shareImage->Det_Mode) { detresult.bDetSaveImg = true; } detresult.searchroi.x -= Det_CropRoi.x; detresult.searchroi.y -= Det_CropRoi.y; // if (true) // { // detresult.bsaveprocessimg = true; // } cv::Mat detImg_mask = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask; cv::Mat detimg = L255CutImg; int re = m_MarkDet.Detect(detimg, &detresult); if (re != 0) { return re; } if (detresult.nresult != 0) { return -1; } // printf("-------------------22222 \n"); // detresult.markRoi.x -= Det_CropRoi.x; // detresult.markRoi.y -= Det_CropRoi.y; int sheild_h = detresult.markRoi.height; if (sheild_h < pFuntion->x_sheild_width) { sheild_h = pFuntion->x_sheild_width; } int sheild_w = detresult.markRoi.width; if (sheild_w < pFuntion->y_sheild_width) { sheild_w = pFuntion->y_sheild_width; } int pc_x = detresult.markRoi.x + detresult.markRoi.width * 0.5; int pc_y = detresult.markRoi.y + detresult.markRoi.height * 0.5; cv::Rect sheildRoi; sheildRoi.x = pc_x - sheild_w * .5; sheildRoi.y = pc_y - sheild_h * .5; sheildRoi.width = sheild_w; sheildRoi.height = sheild_h; if (CheckUtil::RoiInImg(sheildRoi, detImg_mask)) { detImg_mask(sheildRoi).setTo(255); } cv::Rect sheild_x_roi; sheild_x_roi.x = 0; sheild_x_roi.y = pc_y - sheild_h * .5; sheild_x_roi.width = detImg_mask.cols; sheild_x_roi.height = sheild_h; pMarkLineResult->markLine_Roi_X = sheild_x_roi; if (CheckUtil::RoiInImg(sheild_x_roi, detImg_mask) && pFuntion->bUse_Roi_Sheild) { detImg_mask(sheild_x_roi).setTo(255); } cv::Rect sheild_y_roi; sheild_y_roi.x = pc_x - sheild_w * 0.5; sheild_y_roi.y = 0; sheild_y_roi.width = sheild_w; sheild_y_roi.height = detImg_mask.rows; pMarkLineResult->markLine_Roi_Y = sheild_y_roi; if (CheckUtil::RoiInImg(sheild_y_roi, detImg_mask) && pFuntion->bUse_Roi_Sheild) { detImg_mask(sheild_y_roi).setTo(255); } pMarkLineResult->nresult = 1; return 0; } int BQ_Det(cv::Mat detimg, shared_ptr pBQ_Result) { cv::resize(detimg, detimg, cv::Size(), 0.1, 0.1); cv::Mat detimg_bin; cv::GaussianBlur(detimg, detimg, cv::Size(3, 3), 0); cv::threshold(detimg, detimg_bin, 25, 255, cv::THRESH_BINARY_INV); vector> contours; cv::Rect result_roi; findContours(detimg_bin, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // 找到最大轮廓 double max_area = 0; int max_contour_index = 0; for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]); if (area > max_area) { max_area = area; max_contour_index = i; } } if (max_contour_index < 0) { cerr << "No contours found!" << endl; return 7; } cv::Rect r_rect = boundingRect(contours[max_contour_index]); cv::Rect rect(r_rect.x*10, r_rect.y*10, r_rect.width*10, r_rect.height*10); if (max_contour_index >= 0) { pBQ_Result->pBQ_roiList.push_back(rect); } return 0; } int CameraCheckAnalysisy::preDet_ZF(const cv::Mat &L255CutImg, std::shared_ptr L255) { long ts = CheckUtil::getcurTime(); m_pCheck_Result->cameraBaseResult->pZF_Result = std::make_shared(); m_pCheck_Result->cameraBaseResult->pZF_Result->bShield_ZF = m_AnalysisyConfig.commonCheckConfig.baseConfig.bShield_ZF; cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi; AI_ZF_Det::DetConfigResult detresult; detresult.strCamName = m_strcameraName; detresult.bDebugsaveimg = L255->result->in_shareImage->bDebugsaveImg; detresult.pdetlog = m_pdetlog; if (DET_MODE_ZF == L255->result->in_shareImage->Det_Mode) { detresult.bDetSaveImg = true; } detresult.pZF_Result = m_pCheck_Result->cameraBaseResult->pZF_Result; cv::Mat detimg = L255CutImg; int re = m_ZF_Det.Detect(detimg, &detresult); if (re != 0) { return re; } // 如果要屏蔽字符 if (m_pCheck_Result->cameraBaseResult->pZF_Result->bShield_ZF) { m_pdetlog->AddCheckstr(PrintLevel_2, "preDet_ZF", "shieldZF is Open"); cv::Mat detImg_mask = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask; for (int i = 0; i < m_pCheck_Result->cameraBaseResult->pZF_Result->pZF_roiList.size(); i++) { cv::Rect boundingRect = m_pCheck_Result->cameraBaseResult->pZF_Result->pZF_roiList.at(i); detImg_mask(boundingRect).setTo(255); } if (L255->result->in_shareImage->bDebugsaveImg) { cv::imwrite("sheildImg.png", m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask); } } else { m_pdetlog->AddCheckstr(PrintLevel_2, "preDet_ZF", "shieldZF is false"); } std::shared_ptr pZF_Result = m_pCheck_Result->cameraBaseResult->pZF_Result; // zf 检测结果 pZF_Result->ZF_centerPoint.erase(pZF_Result->ZF_centerPoint.begin(), pZF_Result->ZF_centerPoint.end()); for (int i = 0; i < pZF_Result->pZF_roiList.size(); i++) { // 获取当前轮廓的边界矩形 cv::Rect boundingRect = pZF_Result->pZF_roiList.at(i); cv::Point p; p.x = boundingRect.x + boundingRect.width * 0.5f; p.y = boundingRect.y + boundingRect.height * 0.5f; // printf("--- zf %d %d %d %d \n", boundingRect.x, boundingRect.y, boundingRect.width, boundingRect.height); pZF_Result->ZF_centerPoint.push_back(p); } if (L255->result->in_shareImage->bDebugsaveImg) { cv::Mat showimg = detimg.clone(); for (int i = 0; i < m_pCheck_Result->cameraBaseResult->pZF_Result->pZF_roiList.size(); i++) { cv::Rect boundingRect = m_pCheck_Result->cameraBaseResult->pZF_Result->pZF_roiList.at(i); cv::rectangle(showimg, boundingRect, cv::Scalar(200), 5); } cv::imwrite("zf_result.png", showimg); } m_pCheck_Result->cameraBaseResult->pZF_Result->nresult = 0; long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, "preDet_ZF", "==================End zf num %ld re = %d time %ld ms ", m_pCheck_Result->cameraBaseResult->pZF_Result->pZF_roiList.size(), re, te - ts); return 0; } int CameraCheckAnalysisy::preDet_BQ(const cv::Mat &L255CutImg, std::shared_ptr L255) { long ts = CheckUtil::getcurTime(); m_pCheck_Result->cameraBaseResult->pBQ_Result = std::make_shared(); m_pCheck_Result->cameraBaseResult->pBQ_Result->bShield_BQ = m_AnalysisyConfig.commonCheckConfig.baseConfig.bShield_BQ; cv::Rect Det_CropRoi = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->cutRoi; AI_BQ_Det::DetConfigResult detresult; detresult.strCamName = m_strcameraName; detresult.bDebugsaveimg = L255->result->in_shareImage->bDebugsaveImg; detresult.pdetlog = m_pdetlog; if (DET_MODE_ZF == L255->result->in_shareImage->Det_Mode) { detresult.bDetSaveImg = true; } detresult.pBQ_Result = m_pCheck_Result->cameraBaseResult->pBQ_Result; cv::Mat detimg = L255CutImg; int re = m_BQ_Det.Detect(detimg, &detresult); if (re != 0) { return re; } // 如果要屏蔽标签 if (m_pCheck_Result->cameraBaseResult->pBQ_Result->bShield_BQ) { m_pdetlog->AddCheckstr(PrintLevel_2, "preDet_BQ", "shieldBQ is Open"); cv::Mat detImg_mask = m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask; for (int i = 0; i < m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.size(); i++) { cv::Rect boundingRect = m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.at(i); boundingRect.x -= 5; boundingRect.y -= 5; boundingRect.width += 10; boundingRect.height += 10; detImg_mask(boundingRect).setTo(255); } if (L255->result->in_shareImage->bDebugsaveImg) { cv::imwrite("sheildImg.png", m_pCheck_Result->cameraBaseResult->pEdgeDetResult->shieldMask); } } else { m_pdetlog->AddCheckstr(PrintLevel_2, "preDet_BQ", "shieldBQ is false"); } std::shared_ptr pBQ_Result = m_pCheck_Result->cameraBaseResult->pBQ_Result; // BQ 检测结果 pBQ_Result->BQ_centerPoint.erase(pBQ_Result->BQ_centerPoint.begin(), pBQ_Result->BQ_centerPoint.end()); for (int i = 0; i < pBQ_Result->pBQ_roiList.size(); i++) { // 获取当前轮廓的边界矩形 cv::Rect boundingRect = pBQ_Result->pBQ_roiList.at(i); cv::Point p; p.x = boundingRect.x + boundingRect.width * 0.5f; p.y = boundingRect.y + boundingRect.height * 0.5f; // printf("--- zf %d %d %d %d \n", boundingRect.x, boundingRect.y, boundingRect.width, boundingRect.height); pBQ_Result->BQ_centerPoint.push_back(p); } if (L255->result->in_shareImage->bDebugsaveImg) { cv::Mat showimg = detimg.clone(); for (int i = 0; i < m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.size(); i++) { cv::Rect boundingRect = m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.at(i); cv::rectangle(showimg, boundingRect, cv::Scalar(200), 5); } cv::imwrite("bq_result.png", showimg); } m_pCheck_Result->cameraBaseResult->pBQ_Result->nresult = 0; long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, "preDet_BQ", "==================End bq num %ld re = %d time %ld ms ", m_pCheck_Result->cameraBaseResult->pBQ_Result->pBQ_roiList.size(), re, te - ts); return 0; } int CameraCheckAnalysisy::Init(std::string strcameraName) { m_strcameraName = strcameraName; printf("CameraCheckAnalysisy::Init start \n"); SetNewConfig(); int re = 0; re = InitCheckAnalysisy(); if (CHECK_OK != re) { printf("InitCheckAnalysisy error\n"); return -1; } re = InitRun(); if (CHECK_OK != re) { printf("InitRun error\n"); m_nErrorCode = re; return m_nErrorCode; } // m_pQX_Merge_Analysis->SetbaseCheckFunction(m_strcameraName, m_pChannelFuntion, m_pbaseCheckFunction); printf("CameraCheckAnalysisy::Init end \n"); return 0; } int CameraCheckAnalysisy::StartCheck(std::shared_ptr pCamera_Check_Result) { if (m_bHaveImgeDet) { return -1; } { std::lock_guard lock(mtx_WaiteImg); m_pCheck_Result = pCamera_Check_Result; if (m_pCheck_Result->bJson) { // 如果是 复测 直接进入 参数判断阶段。 m_pCheck_Result->SetCheckStep(Check_Step_ResultParamJudg); // 进入预处理阶段 } else { // m_pCheck_Result->SetCheckStep(Check_Step_PreDet); // 进入预处理阶段 } m_bHaveImgeDet = true; m_pdetlog = m_pCheck_Result->detlog; m_pdetlog->AddCheckstr(PrintLevel_0, "Camera StartCheck", "==================start %s", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); } cond_WaiteImg.notify_all(); return 0; } int CameraCheckAnalysisy::StartThread() { m_bExit = false; // 开启检测线程 ptr_thread_Run = std::make_shared(std::bind(&CameraCheckAnalysisy::Run, this)); return 0; } int CameraCheckAnalysisy::StopThread() { m_bExit = true; if (ptr_thread_Run != nullptr) { if (ptr_thread_Run->joinable()) { ptr_thread_Run->join(); } } return 0; } int CameraCheckAnalysisy::InitRun() { int re; re = StartThread(); if (CHECK_OK != re) { return re; } m_bInitSucc = true; // 检测前更新参数 SetNewConfig(); return 0; } int CameraCheckAnalysisy::InitCheckAnalysisy() { int re = 0; for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++) { RunInfoST RunConfig; RunConfig.nThreadIdx = i; m_pImgCheckAnalysisy[i] = ImgCheckBase::GetInstance(); re = m_pImgCheckAnalysisy[i]->UpdateConfig((void *)&RunConfig, CHECK_CONFIG_Run); if (re != 0) { printf("UpdateConfig %d Fail %s\n", CHECK_CONFIG_Run, m_pImgCheckAnalysisy[i]->GetErrorInfo().c_str()); return re; } re = m_pImgCheckAnalysisy[i]->UpdateConfig((void *)m_pConfig.get(), CHECK_CONFIG_Module); if (re != 0) { printf("UpdateConfig %d Fail %s\n", CHECK_CONFIG_Module, m_pImgCheckAnalysisy[i]->GetErrorInfo().c_str()); return re; } re = m_pImgCheckAnalysisy[i]->RunStart(); if (re != 0) { printf("cami %s RunStart Fail ==%d\n", m_strcameraName.c_str(), re); return re; } printf(">>>>cami %s InitCheckAnalysisy: ImgCheckThread %d / %d Start Succ \n", m_strcameraName.c_str(), i, IMGCHECKANALYSISY_NUM); if (re != 0) { return re; } } return 0; } int CameraCheckAnalysisy::CheckImgRun() { std::string strCameraName = m_pCheck_Result->cameraBaseResult->strCameraName; int re = 0; Check_Step curcheckStep = m_pCheck_Result->GetCheckStep(); m_pdetlog->AddCheckstr(PrintLevel_1, "CheckImgRun", "Cam %s ------Product_Off_X_mm %f ", m_strcameraName.c_str(), m_AnalysisyConfig.commonCheckConfig.baseConfig.fProduct_Off_X_mm); // 如果是未检测状态,则开始预处理 if (curcheckStep == Check_Step_NODet) { std::string strconfigchannel = m_pbaseCheckFunction->edgeChannel.strChannel; if (strconfigchannel == "") { strconfigchannel = "L255"; } if (m_pCheck_Result->IsHaveL255()) { curcheckStep = Check_Step_PreDet; // 进入到预图片检测阶段 m_pCheck_Result->SetCheckStep(curcheckStep); m_pdetlog->AddCheckstr(PrintLevel_1, "CheckImgRun", "cam %s : Have L255 Img Start Check_Step_PreDet", strCameraName.c_str()); } else { if (!m_pCheck_Result->getImgPushComplate()) { return 1; } else { m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "Error cam %s : NO L255 Img", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); curcheckStep = Check_Step_ImgeDet_End; // 图片送图完成, 没有 L255 强制 结束 m_pCheck_Result->SetCheckStep(curcheckStep); } } } m_pdetlog->AddCheckstr(PrintLevel_1, "CheckImgRun", "Cam %s ------------curcheckStep:%d ", m_strcameraName.c_str(), curcheckStep); // getchar(); // 检测前更新参数 SetNewConfig(); // 预处理 if (curcheckStep == Check_Step_PreDet) { // m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "cam %s : Check_Step_PreDet", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); int re = Detect_Pre(); if (re != 0) { // 图片 送图没有完成,则继续等待。 if (!m_pCheck_Result->getImgPushComplate()) { return 1; } else { m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "Error cam %s : Detect_Pre error", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); curcheckStep = Check_Step_ImgeDet_End; // Detect_Pre error m_pCheck_Result->SetCheckStep(curcheckStep); } } else { if (re == 9) { curcheckStep = Check_Step_ImgeDet_End; // 边缘检测模式,直接退出 m_pCheck_Result->SetCheckStep(curcheckStep); } else { curcheckStep = Check_Step_ImgeDet; // 进入检测 m_pCheck_Result->SetCheckStep(curcheckStep); } } } // 检测每张图片 if (curcheckStep == Check_Step_ImgeDet) { // m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "cam %s : Check_Step_ImgeDet", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); // 检测每张图片 re = Detect_Images(); if (re != 0) { // 图片 送图没有完成,则继续等待。 if (!m_pCheck_Result->getImgPushComplate()) { return 1; } else { m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "Error cam %s : Detect_Images error", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); curcheckStep = Check_Step_ImgeDet_End; // Detect_Images error m_pCheck_Result->SetCheckStep(curcheckStep); } } else { curcheckStep = Check_Step_ResultParamJudg; // 进入到测结果进行参数判断 m_pCheck_Result->SetCheckStep(curcheckStep); } } // 对检测结果进行参数判断,判断是否NG. if (curcheckStep == Check_Step_ResultParamJudg) { // m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "cam %s : Check_Step_ResultParamJudg", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); // 检测每张图片 re = ResultParamJudge(); // 如果有异常 if (re != 0) { // 图片 送图没有完成,则继续等待。 if (!m_pCheck_Result->getImgPushComplate()) { return 1; } else { m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "Error cam %s : ResultParamJudge error", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); curcheckStep = Check_Step_ImgeDet_End; // ResultParamJudge error m_pCheck_Result->SetCheckStep(curcheckStep); } } else { curcheckStep = Check_Step_ImgeDet_End; // 检测结束 m_pCheck_Result->SetCheckStep(curcheckStep); } } // 图片检测完成 if (curcheckStep == Check_Step_ImgeDet_End) { // m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "cam %s : Check_Step_ImgeDet_End", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); // 所有图片都送完了。 if (m_pCheck_Result->getImgPushComplate()) { curcheckStep = Check_Step_Complete; m_pCheck_Result->SetCheckStep(curcheckStep); } else { // printf("========came %s wait img send end \n", m_strcameraName.c_str()); } } // 处理完成 if (curcheckStep == Check_Step_Complete) { long tend = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "cam %s : Check_Step_Complete", m_pCheck_Result->cameraBaseResult->strCameraName.c_str()); std::string strTimg = CheckUtil::getCurTimeHMS(); m_pdetlog->AddCheckstr(PrintLevel_0, "CheckImgRun", "========came %s Check ALL end time %ld ms %s", m_pCheck_Result->cameraBaseResult->strCameraName.c_str(), tend - m_pCheck_Result->time_start, strTimg.c_str()); InsertCameraLog(); ngImgSave(); std::lock_guard lock(mtx_WaiteImg); m_bHaveImgeDet = false; m_pCheck_Result.reset(); } // m_pdetlog->printLog(m_strcameraName); return 0; } int CameraCheckAnalysisy::Run() { while (!m_bExit) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); WaitDetImg(); int re = CheckImgRun(); } return 0; } int CameraCheckAnalysisy::ImgEdge(cv::Mat img, cv::Mat &detMaskImg, cv::Rect &roi, int productIdx) { int re = 0; return re; } int CameraCheckAnalysisy::InsertCameraLog() { int ImageNum = m_pCheck_Result->ImageALLDetResultList.size(); for (int imgidx = 0; imgidx < ImageNum; imgidx++) { std::shared_ptr pImageResult = m_pCheck_Result->ImageALLDetResultList.at(imgidx); std::shared_ptr m_CheckResult_shareP = pImageResult->result; // 返回结果 // 1、把图片的相关日志 写到 返回 日志中。 m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), pImageResult->detlog->logList.begin(), pImageResult->detlog->logList.end()); std::string str = ""; char buffer[256]; // 2、把缺陷信息 写的 返回日志中。 { std::shared_ptr pDetResult = pImageResult->pDetResult; // 检测结果 int qxNum = 0; if (pDetResult->pQx_ErrorList) { qxNum = pDetResult->pQx_ErrorList->size(); { sprintf(buffer, " =====================NG num %d=============================", pImageResult->NG_num); str = buffer; m_CheckResult_shareP->det_LogList.push_back(str); } for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); if (QX_info->result == QX_RESULT_TYPE_NG) { std::shared_ptr pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), pQxLog->logList.begin(), pQxLog->logList.end()); } } { sprintf(buffer, " =====================YS num %d=============================", pImageResult->YS_num); str = buffer; m_CheckResult_shareP->det_LogList.push_back(str); } for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); if (QX_info->result == QX_RESULT_TYPE_YS) { std::shared_ptr pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), pQxLog->logList.begin(), pQxLog->logList.end()); } } { sprintf(buffer, " =====================OK num %d=============================", pImageResult->Ok_num); str = buffer; m_CheckResult_shareP->det_LogList.push_back(str); } for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); if (QX_info->result == QX_RESULT_TYPE_OK) { std::shared_ptr pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), pQxLog->logList.begin(), pQxLog->logList.end()); } } { sprintf(buffer, " =====================NO Judge num %d=============================", pImageResult->NoJudge_num); str = buffer; m_CheckResult_shareP->det_LogList.push_back(str); } for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); if (QX_info->result == QX_RESULT_TYPE_NoJduge) { std::shared_ptr pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), pQxLog->logList.begin(), pQxLog->logList.end()); } } } } { sprintf(buffer, " =====================Cam Log ============================="); str = buffer; m_CheckResult_shareP->det_LogList.push_back(str); } // 3、把相机的日志 写到 返回日志中。 m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_pCheck_Result->detlog->logList.begin(), m_pCheck_Result->detlog->logList.end()); { sprintf(buffer, " =====================Product Log ============================="); str = buffer; m_CheckResult_shareP->det_LogList.push_back(str); } // 4、把产品相关日志 写到 返回日志中。 m_CheckResult_shareP->det_LogList.insert(m_CheckResult_shareP->det_LogList.end(), m_pCheck_Result->productBaseResult->detlog->logList.begin(), m_pCheck_Result->productBaseResult->detlog->logList.end()); } return 0; } int 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; } static std::string SanitizePathComponent(const std::string& input) { std::string result; result.reserve(input.size()); for (char ch : input) { // 只允许字母、数字、下划线、点、短横线,其余替换为下划线 if (isalnum(static_cast(ch)) || ch == '_' || ch == '.' || ch == '-') { result.push_back(ch); } else { result.push_back('_'); } } // 防止相对路径伪装(如 ".", "..") if (result == "." || result == "..") { result = "_"; } return result; } int CameraCheckAnalysisy::ngImgSave() { // 拷贝智能指针,保证在异步任务中引用计数有效 auto result_copy = m_pCheck_Result; std::string save_path_root = "/home/aidlux/BOE/FOG/cloud/"; auto task = std::async(std::launch::async, [result_copy, save_path_root]() { try { if (!result_copy) return; // ---------- 目录清理(加锁防止并发删除)---------- { static std::mutex cleanup_mutex; // 静态锁,所有实例共享 std::lock_guard lock(cleanup_mutex); DIR* dir = opendir(save_path_root.c_str()); if (dir) { std::vector> dirs; struct dirent* entry; while ((entry = readdir(dir)) != nullptr) { std::string name = entry->d_name; if (name == "." || name == "..") continue; std::string full_path = save_path_root + name; struct stat st; if (stat(full_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { struct stat lst; if (lstat(full_path.c_str(), &lst) == 0 && !S_ISLNK(lst.st_mode)) { dirs.emplace_back(full_path, st.st_mtime); } } } closedir(dir); if (dirs.size() > 100) { std::sort(dirs.begin(), dirs.end(), [](auto& a, auto& b) { return a.second < b.second; }); const std::string& oldest_dir = dirs.front().first; if (!oldest_dir.empty() && oldest_dir != save_path_root) { CheckUtil::DeleteDir(oldest_dir); } } } else { cerr << ("ERROR: cannot open root directory for cleanup"); } } // ---------- 保存NG图像 ---------- int ImageNum = static_cast(result_copy->ImageALLDetResultList.size()); for (int imgidx = 0; imgidx < ImageNum; ++imgidx) { auto pImageResult = result_copy->ImageALLDetResultList.at(imgidx); if (!pImageResult) continue; auto m_CheckResult_shareP = pImageResult->result; if (!m_CheckResult_shareP) continue; // 提取并净化路径组件 std::string raw_product = result_copy->productBaseResult ? result_copy->productBaseResult->strproductName : "unknown"; std::string raw_camera = result_copy->cameraBaseResult ? result_copy->cameraBaseResult->strCameraName : "unknown"; std::string raw_channel = m_CheckResult_shareP->basicResult.strChannel; std::string safe_product = SanitizePathComponent(raw_product); std::string safe_camera = SanitizePathComponent(raw_camera); std::string safe_channel = SanitizePathComponent(raw_channel); // 只保存NG结果且图像数据非空 if ((m_CheckResult_shareP->nresult == 1 || safe_channel == "L255") && !m_CheckResult_shareP->resultMaskImg.empty() && !m_CheckResult_shareP->resultimg.empty() && !m_CheckResult_shareP->cutSrcimg.empty()) { // 构建保存目录(使用净化后的组件) std::string save_dir = save_path_root + "/" + safe_product + "/" + safe_camera + "/"; if (CheckUtil::CreateDir(save_dir) != 0) { cerr << ("Failed to create directory: " + save_dir); continue; } // 深拷贝图像数据,避免原始数据被其他线程修改 cv::Mat mask_img = m_CheckResult_shareP->resultMaskImg.clone(); cv::Mat result_img = m_CheckResult_shareP->resultimg.clone(); cv::Mat cut_img = m_CheckResult_shareP->cutSrcimg.clone(); try { // cv::imwrite(save_dir + safe_channel + "_AIMask.png", mask_img); // cv::imwrite(save_dir + safe_channel + "_Resultimg.png", result_img); // cv::imwrite(save_dir + safe_channel + "_CutImg.png", cut_img); writeLog(save_dir+ safe_channel + "log", m_CheckResult_shareP->det_LogList); } catch (const cv::Exception& e) { cerr << ("OpenCV exception: " + std::string(e.what())); } catch (const std::exception& e) { cerr << ("Standard exception: " + std::string(e.what())); } catch (...) { cerr << ("Unknown exception during image save"); } } } } catch (const std::exception& e) { cerr << ("Future get exception: " + std::string(e.what())); } catch (...) { cerr << ("Future get unknown exception"); } }); // ---------- 管理 future 队列(清理已完成任务)---------- { std::lock_guard lock(g_ngImgSave_mutex); g_ngImgSave_futures.emplace_back(std::move(task)); size_t write_idx = 0; for (size_t i = 0; i < g_ngImgSave_futures.size(); ++i) { auto& f = g_ngImgSave_futures[i]; // 检查任务是否已就绪(非阻塞) if (f.valid() && f.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { try { f.get(); } catch (const std::exception& e) { cerr << ("Future get exception: " + std::string(e.what())); } catch (...) { cerr << ("Future get unknown exception"); } } else { // 保留未完成的任务 if (i != write_idx) { g_ngImgSave_futures[write_idx] = std::move(g_ngImgSave_futures[i]); } ++write_idx; } } g_ngImgSave_futures.resize(write_idx); // 限制队列最大长度,防止无限堆积(例如超过100则丢弃最老的任务) const size_t MAX_PENDING_TASKS = 20; if (g_ngImgSave_futures.size() > MAX_PENDING_TASKS) { // 丢弃最早未完成的任务(注意:需要确保其可被销毁,不阻塞) g_ngImgSave_futures.erase(g_ngImgSave_futures.begin()); } } return 0; } ChannelCheckFunction *CameraCheckAnalysisy::GetChannelFuntion(std::string strChannelName) { ChannelCheckFunction *p = NULL; // printf("m_pChannelFuntion->channelFunctionArr.size() %zu\n", m_pChannelFuntion->channelFunctionArr.size()); for (int i = 0; i < m_pChannelFuntion->channelFunctionArr.size(); i++) { if (CheckUtil::compareIgnoreCase(m_pChannelFuntion->channelFunctionArr[i].strChannelName, strChannelName)) { p = &m_pChannelFuntion->channelFunctionArr[i]; } } return p; } int CameraCheckAnalysisy::SetNewConfig() { if (m_pConfig.get() == nullptr) { return 1; } if (m_nConfigIdx < 0) { m_nConfigIdx = m_pConfig->GetConfigIdx(); m_pdetlog->AddCheckstr(PrintLevel_1, "update config", "CameraCheckAnalysisy:%s m_nConfigIdx %d", m_strcameraName.c_str(), m_nConfigIdx); } if (m_pConfig->GetConfigUpdataStatus(ConfigType_Analysisy_Common_XL, m_nConfigIdx)) { m_pConfig->GetConfig(ConfigType_Analysisy_Common_XL, &m_AnalysisyConfig); if (m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.size() > 0) { m_pCommonAnalysisyConfig = &m_AnalysisyConfig.commonCheckConfig.nodeConfigArr.at(0); m_imageResultJudge.UpdateConfig(m_strcameraName); } else { m_pCommonAnalysisyConfig = NULL; printf("m_AnalysisyConfig.commonCheckConfig.nodeConfigArr == 0 \n"); } m_pdetlog->AddCheckstr(PrintLevel_1, "update config", "Get New analysisy config"); // printf("*******ALLImgCheckAnalysisy m_pConfig*********************** Update GetConfig \n"); // m_AnalysisyConfig.checkFunction.print("Update GetConfig"); } return 0; } ImgCheckBase *CameraCheckAnalysisy::GetDealResult(int idx) { // 特殊情况 if (idx >= 0 && idx < IMGCHECKANALYSISY_NUM) { if (CHECK_THREAD_STATUS_IDLE == m_pImgCheckAnalysisy[idx]->GetStatus()) { // printf("*-*-*-*-*-*-*-*- use m_pImgCheckAnalysisy %d \n", idx); return m_pImgCheckAnalysisy[idx]; } else { return NULL; } } int re = 0; int nidx = nLastCheckAnalysisyThreadIdx; for (int i = 0; i < IMGCHECKANALYSISY_NUM; i++) { if (nidx >= IMGCHECKANALYSISY_NUM) { nidx = 0; } if (CHECK_THREAD_STATUS_IDLE == m_pImgCheckAnalysisy[nidx]->GetStatus()) { nLastCheckAnalysisyThreadIdx = nidx + 1; // printf("*-*-*-*-*-*-*-*- use m_pImgCheckAnalysisy %d \n", nidx); return m_pImgCheckAnalysisy[nidx]; } nidx++; } return NULL; }