#include "ImgCheckAnalysisy.hpp" #include "CheckUtil.hpp" #include "Define.h" #include #include "AICommonDefine.h" // 用于排序轮廓的比较函数 static bool compareContourAreas(const vector &contour1, const vector &contour2) { double i = contourArea(contour1); double j = contourArea(contour2); return (i > j); } ImgCheckAnalysisy::ImgCheckAnalysisy() { m_nErrorCode = CHECK_OK; m_nThreadIdx = -1; m_bInitSucc = false; m_bExit = false; m_nRun_Status = CHECK_THREAD_STATUS_IDLE; m_fImgage_Scale_X = 0.03f; m_fImgage_Scale_Y = 0.03f; m_pBasicConfig = NULL; m_strCurDetCamChannel = ""; m_strCurDetChannel = ""; m_pbaseCheckFunction = &m_AnalysisyConfig.baseFunction; m_strLastDate = ""; m_strRootPath_TA_cls = "/home/aidlux/BOE/FOG/Cls/TA/"; m_strRootPath_CA_cls = "/home/aidlux/BOE/FOG/Cls/CA/"; creatsavedir(); m_pImageStorage = ImageStorage::getInstance(); m_nConfigIdx = -1; det_SmallImgNum = 0; } ImgCheckAnalysisy::~ImgCheckAnalysisy() { ExitSystem(); } int ImgCheckAnalysisy::UpdateConfig(void *pconfig, int nConfigType) { int re = 0; switch (nConfigType) { case CHECK_CONFIG_Run: re = LoadRunConfig(pconfig); if (re == 0) { // printf("---> LoadRunConfig Succ\n"); } else { // printf("---> LoadRunConfig Fail\n"); } break; case CHECK_CONFIG_Module: re = LoadCheckConfig(pconfig); if (re == 0) { // printf("---> LoadAnalysisConfig Succ\n"); } else { // printf("---> LoadAnalysisConfig Fail\n"); } break; default: break; } return re; } int ImgCheckAnalysisy::RunStart(void *pconfig1) { // 1 、更新参数 并判断参数是否合法 int re = CHECK_OK; re = SetNewConfig(); if (CHECK_OK != re) { m_nErrorCode = re; return m_nErrorCode; } printf("---> RunStart Start m_RunConfig.nThreadIdx %d \n", m_RunConfig.nThreadIdx); m_nThreadIdx = m_RunConfig.nThreadIdx; re = InitRun(m_RunConfig.nCpu_start_Idx); if (CHECK_OK != re) { m_nErrorCode = re; return m_nErrorCode; } runner = std::make_shared(); runner->Start(); m_nErrorCode = CHECK_OK; // printf("ImgCheckAnalysisy >>>> ImgCheckThread %d Start Succ \n", m_nThreadIdx); return m_nErrorCode; } int ImgCheckAnalysisy::SetDataRun_SharePtr(std::shared_ptr p) { // 设置正在检测 m_pImageAllResult = p; DetImgInfo_shareP = p->result->in_shareImage; m_CheckResult_shareP = p->result; m_pImageAllResult->setStep(ImageAllResult::DetStep_Deting); m_pdetlog = p->detlog; m_pDetResult = p->pDetResult; StartCheck(); m_nErrorCode = CHECK_OK; return m_nErrorCode; } int ImgCheckAnalysisy::GetCheckReuslt(std::shared_ptr &pResult) { m_CheckResult_shareP.reset(); DetImgInfo_shareP.reset(); SetIDLE(); // m_nErrorCode = CHECK_OK; // printf("4 DetImgInfo_shareP count %ld m_nCheckResultErrorCode %d \n", DetImgInfo_shareP.use_count(), m_nCheckResultErrorCode); return m_nCheckResultErrorCode; } int ImgCheckAnalysisy::CheckImg(std::shared_ptr p, std::shared_ptr &pResult) { return 0; } int ImgCheckAnalysisy::ReJsonResul(std::shared_ptr p, std::shared_ptr &pResult) { return 0; } int ImgCheckAnalysisy::InitRun(int nId) { int re = CHECK_OK; if (m_bInitSucc) { return CHECK_OK; } InitModel(); AI_Factory = AIFactory::GetInstance(); m_nRun_Status = CHECK_THREAD_STATUS_IDLE; re = StartThread(nId); if (CHECK_OK != re) { return re; } m_bInitSucc = true; return re; } int ImgCheckAnalysisy::GetStatus() { return m_nRun_Status; } std::string ImgCheckAnalysisy::GetVersion() { return std::string("BOE_1.2.4_" + std::string(__DATE__) + "_" + std::string(__TIME__)); } std::string ImgCheckAnalysisy::GetErrorInfo() { std::string str = GetErrorCodeInfo(m_nErrorCode); printf("%s\n", str.c_str()); return str; } int ImgCheckAnalysisy::creatsavedir() { std::string curDate = CheckUtil::getCurrentDate(); if (curDate == m_strLastDate) { return 0; } m_strLastDate = curDate; m_strRootPath_TA_cls += m_strLastDate + "/"; m_strRootPath_CA_cls += m_strLastDate + "/"; for (int i = 0; i < AI_CLass_QX_NAME_count; i++) { CheckUtil::CreateDir(m_strRootPath_TA_cls + std::to_string(i) + "/"); CheckUtil::CreateDir(m_strRootPath_CA_cls + std::to_string(i) + "/"); } return 0; } int ImgCheckAnalysisy::LoadRunConfig(void *p) { if (p == NULL) { m_nErrorCode = CHECK_ERROR_Config_Null; return m_nErrorCode; } RunInfoST *pconfig = (RunInfoST *)p; m_RunConfig.copy(*pconfig); return CHECK_OK; } int ImgCheckAnalysisy::LoadCheckConfig(void *p) { if (p == NULL) { m_nErrorCode = CHECK_ERROR_Config_Null; return m_nErrorCode; } m_pConfig = (ConfigBase *)p; m_nConfigIdx = m_pConfig->GetConfigIdx(); m_nErrorCode = CHECK_OK; return m_nErrorCode; } // 开启检测 int ImgCheckAnalysisy::StartCheck() { m_nRun_Status = CHECK_THREAD_STATUS_READY; return 0; } int ImgCheckAnalysisy::SetIDLE() { // 更新参数 SetNewConfig(); m_nRun_Status = CHECK_THREAD_STATUS_IDLE; return 0; } int ImgCheckAnalysisy::StartThread(int nId) { // 开启检测线程 ptr_thread_Run = std::make_shared(std::bind(&ImgCheckAnalysisy::Run, this, nId)); if (!m_RunConfig.bRetest) { ptr_thread_AI = std::make_shared(std::bind(&ImgCheckAnalysisy::ThreadTask, this, nId + 1)); } return 0; } int ImgCheckAnalysisy::StopThread() { m_bExit = true; if (ptr_thread_Run != nullptr) { if (ptr_thread_Run->joinable()) { ptr_thread_Run->join(); } } if (ptr_thread_AI != nullptr) { if (ptr_thread_AI->joinable()) { ptr_thread_AI->join(); } } return 0; } int ImgCheckAnalysisy::ExitSystem() { StopThread(); return 0; } int ImgCheckAnalysisy::InitModel() { // 获取当前gpu号确定的 AI处理线程 m_OtherDet_Config.nDeviceId = m_RunConfig.nDeviceId; return 0; } cv::Scalar ImgCheckAnalysisy::calc_blob_info_withstats(cv::Mat &img, const cv::Mat &mask, cv::Rect &stats, cv::Size k_size, int expand, double threshold) { // 解包 stats(x, y, w, h, area) int x = stats.x, y = stats.y, w = stats.width, h = stats.height; // 将图像转换为灰度图像 // 计算感兴趣区域 (ROI) cv::Rect roi(x - expand, y - expand, w + 2 * expand, h + 2 * expand); roi &= cv::Rect(0, 0, img.cols, img.rows); // 确保ROI在图像内 cv::Mat cimg = img(roi); // cv::cvtColor(cimg, cimg, cv::COLOR_BGR2GRAY); // return cv::Scalar(0, 0, 0); // CheckUtil::printROI(roi, "roi-----------"); // printf("img --%d %d \n", img.cols, img.rows); // printf("mask --%d %d \n", mask.cols, mask.rows); cv::Mat cmask = mask(roi); // getchar(); // 扩张掩膜 cv::Scalar mean_bk = cv::mean(cimg, ~cmask); double fbk = mean_bk[0]; cv::Scalar mean_det = cv::mean(cimg, cmask); double fdet = mean_det[0]; // 计算差异图像 cv::Mat diff = cv::abs(cimg - fbk); // cv::imwrite("cimg.png",cimg); // cv::imwrite("cmask.png",cmask); // printf("%f %f - %f \n",fbk,fdet,fbk-fdet); // getchar(); // diff = diff.mul(cmask > 0); cv::Mat masked_image; diff.copyTo(masked_image, cmask); // 计算能量 double energy = cv::sum(masked_image)[0]; // 计算 hj(差异图像大于0的像素均值) // double hj = std::abs(fbk - fdet); double hj = CheckUtil::CalHjWeighted(cimg, cmask, fbk, 2.0f); int worb = 0; if (fdet >= fbk) { worb = 1; } // cv::imwrite("cimg.png", cimg); // cv::imwrite("cmask.png", cmask); // cv::imwrite("diff.png", diff); // cv::imwrite("masked_image.png", masked_image); // printf("fbk %f fdet %f energy %f\n", fbk, fdet, energy); // getchar(); return cv::Scalar(worb, energy, hj); } double ImgCheckAnalysisy::CalBlobHJ(cv::Mat &img, const cv::Mat &mask, cv::Rect &det_roi, cv::Rect &qx_roi, int expand) { int x = qx_roi.x, y = qx_roi.y, w = qx_roi.width, h = qx_roi.height; // 将图像转换为灰度图像 // 计算感兴趣区域 (ROI) cv::Rect roi(x - expand, y - expand, w + 2 * expand, h + 2 * expand); roi &= cv::Rect(det_roi.x, det_roi.y, det_roi.width, det_roi.height); // 确保ROI在图像内 cv::Mat cimg = img(roi).clone(); // cv::cvtColor(cimg, cimg, cv::COLOR_BGR2GRAY); // return cv::Scalar(0, 0, 0); // CheckUtil::printROI(roi, "roi-----------"); // CheckUtil::printROI(det_roi, "det_roi-----------"); // printf("%s img --%d %d \n", m_pImageAllResult->strChannel.c_str(), img.cols, img.rows); // printf("%s mask --%d %d \n", m_pImageAllResult->strChannel.c_str(), mask.cols, mask.rows); cv::Mat cmask = mask(roi).clone(); ; // getchar(); // 扩张掩膜 cv::Scalar mean_bk = cv::mean(cimg, ~cmask); double fbk = mean_bk[0]; cv::Scalar mean_det = cv::mean(cimg, cmask); double fdet = mean_det[0]; // 计算 hj(差异图像大于0的像素均值) // double hj = std::abs(fbk - fdet); double hj = CheckUtil::CalHjWeighted(cimg, cmask, fbk, 2.0f); static int kkk = 0; unsigned char *pErrordata = (unsigned char *)cimg.data; unsigned char *pMaskdata = (unsigned char *)cmask.data; int width = cimg.cols; int height = cimg.rows; long t21 = CheckUtil::getcurTime(); int de = CalHJ_Pixel(pErrordata, pMaskdata, width, height, fbk, 0.3); long t22 = CheckUtil::getcurTime(); // printf("de======= %d usetime %ld \n", de, t22 - t21); std::string strn = m_pImageAllResult->strChannel + "_" + std::to_string(kkk++) + "_" + std::to_string(fbk) + "_" + std::to_string(hj) + "_" + std::to_string(de); // cv::imwrite(strn + "cimg.png", cimg); // cv::imwrite(strn + "cmask.png", cmask); // printf("%s fbk %f fdet %f hj %f\n", m_pImageAllResult->strChannel.c_str(), fbk, fdet, hj); int worb = 0; if (fdet >= fbk) { worb = 1; } return 0.0; } int ImgCheckAnalysisy::CheckRun() { // printf(">>>%s ================start \n", m_pImageAllResult->strBaseInfo.c_str()); long t1, t2, t3, t4, t5, t6, t7; SetNewConfig(); t1 = CheckUtil::getcurTime(); CheckImgInit(); if (DetImgInfo_shareP->bDebugsaveImg) { m_pdetlog->bPrintStr = true; } m_pdetlog->AddCheckstr(PrintLevel_0, "1、basic Info", "---------------------------1、basic Info---------------------------------"); m_pdetlog->AddCheckstr(PrintLevel_0, "Version", "%s", GetVersion().c_str()); m_pdetlog->AddCheckstr(PrintLevel_0, "ConfigVersion", "%s", m_pBasicConfig->strConfigVersion.c_str()); m_pdetlog->AddCheckstr(PrintLevel_0, "Start", "%s", m_pImageAllResult->strBaseInfo.c_str()); m_pdetlog->AddCheckstr(PrintLevel_0, "ImgageScale", "Scale_X = %f Scale_Y = %f", m_fImgage_Scale_X, m_fImgage_Scale_Y); // 返回结果状态初始化 m_CheckResult_shareP->checkStatus = 1; m_CheckResult_shareP->nresult = -1; m_CheckResult_shareP->basicResult.img_id = m_CheckResult_shareP->in_shareImage->img_id; m_CheckResult_shareP->basicResult.imgtype = m_CheckResult_shareP->in_shareImage->imgtype; m_CheckResult_shareP->basicResult.imgstr = m_CheckResult_shareP->in_shareImage->imgstr; m_CheckResult_shareP->basicResult.strChannel = m_CheckResult_shareP->in_shareImage->strChannel; m_strCurDetChannel = m_CheckResult_shareP->basicResult.strChannel; m_strCurDetCamChannel = m_pImageAllResult->cameraBaseResult->strCameraName + "_" + m_strCurDetChannel; // cout << "Version: " << GetVersion() << endl; // cout << "CameraName: " << m_pImageAllResult->cameraBaseResult->strCameraName << endl; // cout << "strChannel: " << m_CheckResult_shareP->basicResult.strChannel<< endl; // 2、参数检查 int rec = ConfigCheck(DetImgInfo_shareP->img); if (rec != CHECK_OK) { m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "ConfigCheck is error type = %d", rec); m_nErrorCode = rec; m_nCheckResultErrorCode = m_nErrorCode; return m_nErrorCode; } m_CutRoi = m_pImageAllResult->cameraBaseResult->pEdgeDetResult->cutRoi; m_Crop_Roi_paramImg = m_CutRoi; m_pImageAllResult->pDetResult->CutRoi = m_CutRoi; m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg; m_pFuntion = GetChannelFuntion(m_strCurDetChannel); int nfunction = 0; if (m_pFuntion != NULL) { m_pdetlog->AddCheckstr(PrintLevel_0, "Detect function", "%s", m_pFuntion->GetInfo("").c_str()); } else { nfunction = 1; m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "m_pFuntion is NULL"); m_nErrorCode = 22; m_nCheckResultErrorCode = m_nErrorCode; return m_nErrorCode; } // 1、检测前 必要的预处理。 DetPreImage(); m_pdetlog->AddCheckstr(PrintLevel_0, "AItask", "=======start:send AI task======="); // 多线程开启 AI 推理检测 long time_AI_s = CheckUtil::getcurTime(); // Other AI m_AI_Other_task = std::make_shared(); m_AI_Other_task->taskname = Task_AI_Other; m_task.sendTask(m_AI_Other_task); // 缺陷检测 m_AItask = std::make_shared(); m_AItask->taskname = Task_AI; m_task.sendTask(m_AItask); ImgPreDet(); // 更新检测区域 Update_DetRoiList(); m_CheckResult_shareP->nresult = 0; // 把临时可以绘制的结果都绘制出来。 DrawResult_Step_1(); long time_AI_e; // AI 推理生成 { long t211 = CheckUtil::getcurTime(); // 对AI的结果进行 处理,等待 AI 推理全部完成。 rec = AIMaskDet(); if (rec != CHECK_OK) { m_nErrorCode = rec; m_nCheckResultErrorCode = m_nErrorCode; return m_nErrorCode; } time_AI_e = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, "4、detect", "-------------------------2、AI Detect--------%ld wait AI complate %ld-------\n", time_AI_e - time_AI_s, time_AI_e - t211); Edge_Det(); m_CheckResult_shareP->resultMaskImg = m_pImageAllResult->qx_DetAIResult->AI_MaskImg; // cv::imwrite("dddddddd.png", m_pImageAllResult->qx_DetAIResult->AI_MaskImg); // if (!m_pImageAllResult->qx_DetAIResult->AI_MaskImg.empty()) // { // cv::imwrite("dddddddd.png", m_pImageAllResult->qx_DetAIResult->AI_MaskImg); // /* code */ // } // else // { // m_pdetlog->AddCheckstr(PrintLevel_0, "4、detect", "m_pImageAllResult->qx_DetAIResult->empty()\n"); // } } { t4 = CheckUtil::getcurTime(); rec = GetCheckResultBLob(); if (rec != CHECK_OK) { m_nErrorCode = rec; m_nCheckResultErrorCode = m_nErrorCode; return m_nErrorCode; } t5 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, "5、BLob ", "------------------------ --------%ld -------\n", t5 - t4); } // m_pdetlog->printLog(m_strCurDetChannel); long te = CheckUtil::getcurTime(); if (m_strCurDetChannel == "Down-Particle") { m_pImageAllResult->cameraBaseResult->DPImg_Status = CameraBaseResult::ImageDet_Status_DetComplete; m_pImageAllResult->cameraBaseResult->DP_MaskImg = m_pImageAllResult->qx_DetAIResult->AI_MaskImg; m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, "cameraBaseResult", "Down-Particle PImg_Status DetComplete %s", CheckUtil::getCurTimeHMS().c_str()); } if (m_strCurDetChannel == "Up-Particle") { m_pImageAllResult->cameraBaseResult->UpImg_Status = CameraBaseResult::ImageDet_Status_DetComplete; m_pImageAllResult->cameraBaseResult->UP_MaskImg = m_pImageAllResult->qx_DetAIResult->AI_MaskImg; m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, "cameraBaseResult", "Up-Particle UpImg_Status DetComplete %s", CheckUtil::getCurTimeHMS().c_str()); } m_pdetlog->AddCheckstr(PrintLevel_1, "result", " ALL use Time %ld AI %ld blob %ld", te - t1, time_AI_e - time_AI_s, t5 - t4); m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, "End", " Check Run"); return 0; } int ImgCheckAnalysisy::SetNewConfig() { if (m_nConfigIdx < 0) { return 1; /* code */ } if (m_pConfig->GetConfigUpdataStatus(ConfigType_Analysisy_Common_XL, m_nConfigIdx)) { printf("************** ImgCheckAnalysisy::SetNewConfig m_nConfigIdx %d\n", 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_pBasicConfig = &m_AnalysisyConfig.commonCheckConfig.baseConfig; m_pRegionAnalysisyParam = &m_pCommonAnalysisyConfig->regionConfigArr.at(0); GetParamidx(); UpdateImgageScale(); UPdateLDConfig(); if (true) { printf("SetNewConfig m_nConfigIdx %d m_CheckConfig.strSkuName %s \n", m_nConfigIdx, m_AnalysisyConfig.strSkuName.c_str()); } } else { printf("m_AnalysisyConfig.commonCheckConfig.nodeConfigArr == 0 \n"); } } else { // printf("ConfigType_Analysisy_Common_XL no Update \n"); } m_nErrorCode = CHECK_OK; return CHECK_OK; } int ImgCheckAnalysisy::GetParamidx() { int region = 0; if (m_pCommonAnalysisyConfig->regionConfigArr.size() <= 0) { return 1; } CheckConfig_Regions_type *p = &m_pCommonAnalysisyConfig->regionConfigArr.at(region).checkConfig_Regions_type[0]; for (int iqx = 0; iqx < CONFIG_QX_NAME_count; iqx++) { m_QxInParamListIdx[iqx] = -1; std::string strqx_name = CONFIG_QX_NAME_Names[iqx]; for (int i = 0; i < p->checkConfig_Regions_Param.size(); i++) { std::string strconfig_name = p->checkConfig_Regions_Param[i].param_name; // getchar(); if (strqx_name == strconfig_name) { printf("strqx_name %s strconfig_name %s \n", strqx_name.c_str(), strconfig_name.c_str()); m_QxInParamListIdx[iqx] = i; break; } } } // getchar(); return 0; } ChannelCheckFunction *ImgCheckAnalysisy::GetChannelFuntion(std::string strChannelName) { ChannelCheckFunction *p = NULL; for (int i = 0; i < m_AnalysisyConfig.checkFunction.channelFunctionArr.size(); i++) { if (CheckUtil::compareIgnoreCase(m_AnalysisyConfig.checkFunction.channelFunctionArr[i].strChannelName, strChannelName)) { p = &m_AnalysisyConfig.checkFunction.channelFunctionArr[i]; } } return p; } int ImgCheckAnalysisy::Run(int nId) { // std::vector vi; // vi.push_back(nId); // auto nRet = set_cpu_id(vi); // printf("Check So %d bind cpu ret %d, %d\n", m_nThreadIdx, nRet, nId); while (!m_bExit) { // 数据准备完成,开启检测 if (m_nRun_Status == CHECK_THREAD_STATUS_READY) { m_nRun_Status = CHECK_THREAD_STATUS_BUSY; /* 检测 */ CheckRun(); m_nRun_Status = CHECK_THREAD_STATUS_COMPLETE; m_pImageAllResult->setStep(ImageAllResult::DetStep_Complet); m_nRun_Status = CHECK_THREAD_STATUS_IDLE; // printf("*--------%d\n", m_nRun_Status); } else { usleep(1000); } // printf("*-"); usleep(1000); } return 0; } int ImgCheckAnalysisy::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 ImgCheckAnalysisy::CalBlob_Other() { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "CalBlob_Other", " Start"); CalBLobMean_GrayDis(); float fs_x = m_fImgage_Scale_X; float fs_y = m_fImgage_Scale_Y; float fs_resize_x = m_pImageAllResult->fscale_detToresult_x; float fs_resize_y = m_pImageAllResult->fscale_detToresult_y; // 遍历每个检测blob for (int i = 0; i < blobs.blobCount; i++) { // m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Blob", "%d/%d start", i, blobs.blobCount); cv::Rect roi; roi.x = blobs.blobTab[i].minx; roi.y = blobs.blobTab[i].miny; roi.width = blobs.blobTab[i].maxx - blobs.blobTab[i].minx + 1; roi.height = blobs.blobTab[i].maxy - blobs.blobTab[i].miny + 1; int config_qx_type = blobs.blobTab[i].ErrType; std::shared_ptr pDetAIResult = m_pImageAllResult->qx_DetAIResult; // 127cell 检测类型。 if (config_qx_type == CONFIG_QX_NAME_white_Cell || config_qx_type == CONFIG_QX_NAME_black_Cell) { pDetAIResult = m_pImageAllResult->cell127_DetAIResult; } cv::Mat maskImg = pDetAIResult->AI_MaskImg; // 精确计算长度 float re_len = Cal_QXLen(maskImg(roi), config_qx_type, fs_x, fs_y); cv::Scalar result = calc_blob_info_withstats(m_pImageAllResult->detImg, maskImg, roi); int QX_whiteBLACK = CONFIG_QX_BLACK; if (result[0] > 0) { QX_whiteBLACK = CONFIG_QX_WHITE; } double energe = result[1]; blobs.blobTab[i].energy = energe; float JudgArea = blobs.blobTab[i].area * fs_x * fs_y; blobs.blobTab[i].JudgArea = JudgArea; float flen = roi.width * fs_x; if (roi.height * fs_y > flen) { flen = roi.height * fs_y; } if (re_len > flen) { flen = re_len; } blobs.blobTab[i].len = flen; // m_pdetlog->AddCheckstr(PrintLevel_3, " CalBlob_Other ", "qx %d ErrType %d ", i, blobs.blobTab[i].ErrType); } return 0; } int ImgCheckAnalysisy::CalBLobMean_GrayDis() { if (blobs.blobCount <= 0) { return 0; } cv::Size sz; sz.width = 640; sz.height = 480; cv::Mat temimg; cv::resize(m_pImageAllResult->detImg, temimg, sz, 0, 0, 1); cv::Rect roi1; roi1.x = 0; roi1.y = 0; roi1.width = temimg.cols; roi1.height = temimg.rows; cv::Rect roi2; roi2.x = 0; roi2.y = 0; roi2.width = temimg.cols; roi2.height = temimg.rows; int mean1 = 0; int mean2 = 0; // 上黑下白 。。。。 if (m_pImageAllResult->bWhiteOrBlackImg) { m_pImageAllResult->pWTB_Check_Result = std::make_shared(); cv::Mat binary_image; // 应用模糊 cv::blur(temimg, temimg, cv::Size(3, 3)); // 15x15 的模糊核 cv::threshold(temimg, binary_image, 100, 255, cv::THRESH_BINARY); // 寻找轮廓 std::vector> contours; cv::findContours(binary_image, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 找到最大轮廓 double max_area = 0; int max_area_contour_index = -1; for (size_t i = 0; i < contours.size(); ++i) { double area = cv::contourArea(contours[i]); if (area > max_area) { max_area = area; max_area_contour_index = i; } } // cv::imwrite("temimg123.png", temimg); // cv::imwrite("binary_image.png", binary_image); // printf("max_area_contour_index %d \n", max_area_contour_index); // getchar(); if (max_area_contour_index >= 0) { float fx = m_pImageAllResult->detImg.cols * 1.0f / temimg.cols; float fy = m_pImageAllResult->detImg.rows * 1.0f / temimg.rows; float fs_resize_x = m_pImageAllResult->fscale_detToresult_x; float fs_resize_y = m_pImageAllResult->fscale_detToresult_y; // 计算最大轮廓的外接矩形 cv::Rect bounding_rect = cv::boundingRect(contours[max_area_contour_index]); cv::Rect roi_wtb = bounding_rect; if (roi_wtb.x < 5) { roi_wtb.x = 0; } // printf(" \n\n\n\n\n%d %d %d %d %d %d \n\n",roi_wtb.x ,roi_wtb.y ,roi_wtb.width ,roi_wtb.height,temimg.cols,temimg.rows); if (temimg.cols - (roi_wtb.x + roi_wtb.width) < 5) { roi_wtb.width = temimg.cols - roi_wtb.x; } // printf(" \n\n\n\n\n%d %d %d %d %d %d \n\n",roi_wtb.x ,roi_wtb.y ,roi_wtb.width ,roi_wtb.height,temimg.cols,temimg.rows); if (roi_wtb.y < 5) { roi_wtb.y = 0; } if (temimg.rows - (roi_wtb.y + roi_wtb.height) < 5) { roi_wtb.height = temimg.rows - roi_wtb.y; } m_pImageAllResult->pWTB_Check_Result->roi_src.x = roi_wtb.x * fx; m_pImageAllResult->pWTB_Check_Result->roi_src.y = roi_wtb.y * fy; m_pImageAllResult->pWTB_Check_Result->roi_src.width = roi_wtb.width * fx; m_pImageAllResult->pWTB_Check_Result->roi_src.height = roi_wtb.height * fy; // printf(" \n\n\n\n\n%d %d %d %d %d %d \n\n",m_OtherResult.WTB_Check_Result.roi_src.x ,m_OtherResult.WTB_Check_Result.roi_src.y ,m_OtherResult.WTB_Check_Result.roi_src.width ,m_OtherResult.WTB_Check_Result.roi_src.height, m_TemCheck.temImgList[TEM_IMG_IDX_SrcCrop].cols, m_TemCheck.temImgList[TEM_IMG_IDX_SrcCrop].rows); m_pImageAllResult->pWTB_Check_Result->roi_show.x = m_pImageAllResult->pWTB_Check_Result->roi_src.x * fs_resize_x; m_pImageAllResult->pWTB_Check_Result->roi_show.y = m_pImageAllResult->pWTB_Check_Result->roi_src.y * fs_resize_y; m_pImageAllResult->pWTB_Check_Result->roi_show.width = m_pImageAllResult->pWTB_Check_Result->roi_src.width * fs_resize_x; m_pImageAllResult->pWTB_Check_Result->roi_show.height = m_pImageAllResult->pWTB_Check_Result->roi_src.height * fs_resize_y; // printf(" \n\n\n\n\n%d %d %d %d %d %d \n\n",m_OtherResult.WTB_Check_Result.roi_show.x ,m_OtherResult.WTB_Check_Result.roi_show.y ,m_OtherResult.WTB_Check_Result.roi_show.width ,m_OtherResult.WTB_Check_Result.roi_show.height,m_TemCheck.temImgList[TEM_IMG_IDX_Result].cols,m_TemCheck.temImgList[TEM_IMG_IDX_Result].rows); int dis_w = std::abs(bounding_rect.width - temimg.cols); int dis_h = std::abs(bounding_rect.height - temimg.rows); if (dis_w < dis_h) { int line_h_up = std::abs(bounding_rect.y - 0); int line_h_dpwn = std::abs(bounding_rect.y + bounding_rect.height - temimg.rows); if (line_h_up > line_h_dpwn) { roi1.x = 0; roi1.y = 0; roi1.width = temimg.cols; roi1.height = bounding_rect.y; roi2.x = 0; roi2.y = bounding_rect.y; roi2.width = temimg.cols; roi2.height = temimg.rows - bounding_rect.y; } else { roi1.x = 0; roi1.y = 0; roi1.width = temimg.cols; roi1.height = bounding_rect.y + bounding_rect.height; roi2.x = 0; roi2.y = bounding_rect.y + bounding_rect.height; roi2.width = temimg.cols; roi2.height = temimg.rows - (bounding_rect.y + bounding_rect.height); } } else { int line_w_l = std::abs(bounding_rect.x - 0); int line_w_r = std::abs(bounding_rect.x + bounding_rect.width - temimg.cols); if (line_w_l > line_w_r) { roi1.x = 0; roi1.y = 0; roi1.width = bounding_rect.x; roi1.height = temimg.rows; roi2.x = bounding_rect.x; roi2.y = 0; roi2.width = temimg.cols - bounding_rect.x; roi2.height = temimg.rows; } else { roi1.x = 0; roi1.y = 0; roi1.width = bounding_rect.x + bounding_rect.width; roi1.height = temimg.rows; roi2.x = bounding_rect.x + bounding_rect.width; roi2.y = 0; roi2.width = temimg.cols - (bounding_rect.x + bounding_rect.width); roi2.height = temimg.rows; } } // 是否要存图 if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::Mat showimg; cv::cvtColor(temimg, showimg, cv::COLOR_GRAY2BGR); cv::rectangle(showimg, bounding_rect, cv::Scalar(0, 255, 0), 4); cv::rectangle(showimg, roi1, cv::Scalar(255, 0, 0), 2); cv::rectangle(showimg, roi2, cv::Scalar(0, 0, 255), 2); cv::imwrite(m_strCurDetCamChannel + "graydis.png", showimg); } // cv::Mat showimg; // cv::cvtColor(temimg, showimg, cv::COLOR_GRAY2BGR); // cv::rectangle(showimg, bounding_rect, cv::Scalar(0, 255, 0), 2); // cv::rectangle(showimg, roi1, cv::Scalar(255, 0, 0), 2); // cv::rectangle(showimg, roi2, cv::Scalar(0, 0, 255), 2); // cv::imwrite("ddddd.png", showimg); // getchar(); cv::Rect mean_roi1; int dw1 = roi1.width * 0.1; if (dw1 < 10) { dw1 = 10; } int dh1 = roi1.height * 0.1; if (dh1 < 10) { dh1 = 10; } mean_roi1.x = roi1.x + dw1; mean_roi1.y = roi1.y + dh1; mean_roi1.width = roi1.width - 2 * dw1; mean_roi1.height = roi1.height - 2 * dh1; CheckUtil::CheckRect(mean_roi1, temimg.cols, temimg.rows); cv::Scalar mean_v1 = cv::mean(temimg(mean_roi1)); mean1 = mean_v1[0]; cv::Rect mean_roi2; int dw2 = roi2.width * 0.1; if (dw2 < 10) { dw2 = 10; } int dh2 = roi2.height * 0.1; if (dh2 < 10) { dh2 = 10; } mean_roi2.x = roi2.x + dw2; mean_roi2.y = roi2.y + dh2; mean_roi2.width = roi2.width - 2 * dw2; mean_roi2.height = roi2.height - 2 * dh2; CheckUtil::CheckRect(mean_roi2, temimg.cols, temimg.rows); cv::Scalar mean_v2 = cv::mean(temimg(mean_roi2)); mean2 = mean_v2[0]; if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::Mat showimg; cv::cvtColor(temimg, showimg, cv::COLOR_GRAY2BGR); cv::rectangle(showimg, bounding_rect, cv::Scalar(0, 255, 0), 2); cv::rectangle(showimg, roi1, cv::Scalar(255, 0, 0), 2); cv::rectangle(showimg, roi2, cv::Scalar(0, 0, 255), 2); cv::rectangle(showimg, mean_roi1, cv::Scalar(255, 255, 0), 2); cv::rectangle(showimg, mean_roi2, cv::Scalar(255, 255, 0), 2); cv::imwrite(m_strCurDetCamChannel + "graydis222.png", showimg); } } else { cv::Scalar mean_v1 = cv::mean(temimg(roi1)); mean1 = mean_v1[0]; mean2 = mean1; } } else { cv::Scalar mean_v1 = cv::mean(temimg(roi1)); mean1 = mean_v1[0]; mean2 = mean1; } // printf("mean1 %d mean2 %d\n", mean1, mean2); float fsx = m_pImageAllResult->detImg.cols * 1.0f / temimg.cols; float fsy = m_pImageAllResult->detImg.rows * 1.0f / temimg.rows; roi1.x *= fsx; roi1.y *= fsy; roi1.width *= fsx; roi1.height *= fsy; roi2.x *= fsx; roi2.y *= fsy; roi2.width *= fsx; roi2.height *= fsy; int expand = 20; for (int i = 0; i < blobs.blobCount; i++) { cv::Rect roi; roi.x = blobs.blobTab[i].minx; roi.y = blobs.blobTab[i].miny; roi.width = blobs.blobTab[i].maxx - blobs.blobTab[i].minx + 1; roi.height = blobs.blobTab[i].maxy - blobs.blobTab[i].miny + 1; cv::Point p; p.x = roi.x + roi.width * 0.5; p.y = roi.y + roi.height * 0.5; cv::Rect det_roi = roi1; int mean_v = mean1; if (p.x >= roi1.x && p.x <= (roi1.x + roi1.width) && p.y >= roi1.y && p.y <= (roi1.y + roi1.height)) { mean_v = mean1; det_roi = roi1; } else { mean_v = mean2; det_roi = roi2; } int config_qx_type = blobs.blobTab[i].ErrType; std::shared_ptr pDetAIResult = m_pImageAllResult->qx_DetAIResult; // 127cell 检测类型。 if (config_qx_type == CONFIG_QX_NAME_white_Cell || config_qx_type == CONFIG_QX_NAME_black_Cell) { pDetAIResult = m_pImageAllResult->cell127_DetAIResult; } cv::Mat maskImg = pDetAIResult->AI_MaskImg; CalBlobHJ(m_pImageAllResult->detImg, maskImg, det_roi, roi); // 寻找图像的最大灰度值和其位置 double min_val, max_val; cv::Point min_loc, max_loc; cv::minMaxLoc(m_pImageAllResult->detImg(roi), &min_val, &max_val, &min_loc, &max_loc); // printf("mean %d max %f \n", mean_v, max_val); cv::Scalar mean123 = cv::mean(m_pImageAllResult->detImg(roi)); int mean_roi = mean123[0]; blobs.blobTab[i].maxValue = max_val; blobs.blobTab[i].grayDis = std::abs(mean_v - max_val); // 黑色 if (mean_roi < (mean_v - blobs.blobTab[i].grayDis)) { blobs.blobTab[i].grayDis = std::abs(mean_v - mean_roi); } if (mean_roi < mean_v) { blobs.blobTab[i].whiteOrblack = CONFIG_QX_BLACK; } else { blobs.blobTab[i].whiteOrblack = CONFIG_QX_WHITE; } // 黑色的 if (blobs.blobTab[i].whiteOrblack == CONFIG_QX_BLACK) { if (config_qx_type == CONFIG_QX_NAME_white_Cell || config_qx_type == CONFIG_QX_NAME_black_Cell) { blobs.blobTab[i].ErrType = CONFIG_QX_NAME_black_Cell; } } } return 0; } int ImgCheckAnalysisy::GetClassImg(const cv::Mat &img, cv::Mat &AIdetImg, cv::Rect qx_roi, int detwidth, int detheight) { cv::Rect cutroi; cv::Rect roi = qx_roi; bool bresize = false; { int pc_x = roi.x + roi.width * 0.5; int pc_y = roi.y + roi.height * 0.5; if (roi.width < detwidth && roi.height < detheight) { cutroi.width = detwidth; cutroi.x = pc_x - detwidth * 0.5; cutroi.height = detheight; cutroi.y = pc_y - detheight * 0.5; } else { // 宽 高 if (roi.width > roi.height) { cutroi.width = roi.width + 20; cutroi.x = roi.x - 10; float fsx = detheight * 1.0f / detwidth; cutroi.height = cutroi.width * fsx; cutroi.y = pc_y - cutroi.height * 0.5; } else { cutroi.height = roi.height + 20; cutroi.y = roi.y - 10; float fsy = detwidth * 1.0f / detheight; cutroi.width = cutroi.height * fsy; cutroi.x = pc_x - cutroi.width * 0.5; } bresize = true; } if (cutroi.x < 0) { cutroi.x = 0; } if (cutroi.y < 0) { cutroi.y = 0; } if (cutroi.x + cutroi.width >= img.cols) { cutroi.x = img.cols - cutroi.width; if (cutroi.x < 0) { cutroi.x = 0; if (cutroi.x + cutroi.width >= img.cols) { cutroi.width = img.cols; } } } if (cutroi.y + cutroi.height >= img.rows) { cutroi.y = img.rows - cutroi.height; if (cutroi.y < 0) { cutroi.y = 0; if (cutroi.y + cutroi.height >= img.rows) { cutroi.height = img.rows; } } } } if (!CheckUtil::RoiInImg(cutroi, img)) { return 1; } cv::Size sz; sz.width = detwidth; sz.height = detheight; if (cutroi.width != sz.width || cutroi.height != sz.height) { cv::resize(img(cutroi), AIdetImg, sz); } else { AIdetImg = img(cutroi).clone(); } if (1 != AIdetImg.channels()) { cv::cvtColor(AIdetImg, AIdetImg, cv::COLOR_BGR2GRAY); } return 0; } float ImgCheckAnalysisy::Cal_QXLen(cv::Mat qx_maskImg, int qx_type, float fsc_x, float fsc_y) { float nlen = -1; cv::Mat detimg = qx_maskImg; // 寻找轮廓 vector> contours; cv::findContours(detimg, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // 找到最大面积的轮廓 double maxArea = -1; int maxAreaIdx = -1; for (size_t i = 0; i < contours.size(); ++i) { double area = contourArea(contours[i]); if (area > maxArea) { maxArea = area; maxAreaIdx = i; } } // 如果找到了最大面积的轮廓 if (maxAreaIdx >= 0) { // 使用minAreaRect找到最小外接矩形 cv::RotatedRect rect = cv::minAreaRect(contours[maxAreaIdx]); // // 绘制最小外接矩形 // Point2f vertices[4]; // rect.points(vertices); // for (int i = 0; i < 4; ++i) // { // line(detimg, vertices[i], vertices[(i + 1) % 4], Scalar(128, 255, 0), 2); // 绿色线 // } // 输出结果 // 获取最小外接矩形的尺寸 float width = rect.size.width; float height = rect.size.height; // std::cout << "1 Width: " << width << ", Height: " << height << std::endl; Point2f vertices[4]; rect.points(vertices); vector newcont; for (int i = 0; i < 4; ++i) { Point2f p; p.x = vertices[i].x * fsc_x; p.y = vertices[i].y * fsc_y; newcont.push_back(p); } vector> contours_New; contours_New.push_back(newcont); // Recreate the rotated rectangle with scaled vertices RotatedRect scaledRect = minAreaRect(contours_New[0]); // Calculate scaled width and height width = scaledRect.size.width; height = scaledRect.size.height; // std::cout << "2 width: " << width << ", height: " << height << std::endl; // float scale = 0.5; // 缩放比例 // rect.size.width *= fsc_x; // rect.size.height *= fsc_y; // std::cout << "fsc_x: " << fsc_x << ", fsc_y: " << fsc_y << std::endl; // std::cout << "Width: " << width << ", Height: " << height << std::endl; // 获取最小外接矩形的尺寸 // width = rect.size.width; // height = rect.size.height; if (width > height) { nlen = width; /* code */ } else { nlen = height; } } // getchar(); return nlen; } float ImgCheckAnalysisy::CalImgScorl(cv::Mat det_img, cv::Mat up_img) { float fs = 0; unsigned char *det_img_data = (unsigned char *)det_img.data; unsigned char *up_img_data = (unsigned char *)up_img.data; int w = det_img.cols; int h = det_img.rows; int pitch = w; int offset = 0; int sum_jc = 0; // 交集 都有的 int sum_bj = 0; // 并集 有一个有的 int sum_up = 0; int sum_det = 0; for (int y = 0; y < h; y++) { offset = y * pitch; int kh = 0; for (int x = 0; x < w; x++) { if (det_img_data[offset] != 0 && up_img_data[offset] != 0) { sum_jc++; sum_bj++; sum_up++; sum_det++; } else if (det_img_data[offset] != 0 || up_img_data[offset] != 0) { sum_bj++; if (det_img_data[offset] != 0) { sum_det++; } if (up_img_data[offset] != 0) { sum_up++; } } offset++; } } if (sum_bj != 0) { fs = sum_jc * 1.0f / sum_bj; } m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Up Mask ", "sum_bj %d sum_jc %d sum_up %d sum_det %d", sum_bj, sum_jc, sum_up, sum_det); if (sum_up > sum_det * 2) { // fs = 0; } return fs; } float ImgCheckAnalysisy::CalImgScorl_t(cv::Mat det_img, cv::Mat up_img) { float fs = 0; unsigned char *det_img_data = (unsigned char *)det_img.data; unsigned char *up_img_data = (unsigned char *)up_img.data; int w = det_img.cols; int h = det_img.rows; int pitch = w; int offset = 0; int sum_jc = 0; // 交集 都有的 int sum_bj = 0; // 并集 有一个有的 int sum_up = 0; int sum_det = 0; for (int y = 0; y < h; y++) { offset = y * pitch; int kh = 0; for (int x = 0; x < w; x++) { if (det_img_data[offset] != 0 && up_img_data[offset] != 0) { sum_jc++; sum_bj++; sum_up++; sum_det++; } else if (det_img_data[offset] != 0 || up_img_data[offset] != 0) { sum_bj++; if (det_img_data[offset] != 0) { sum_det++; } if (up_img_data[offset] != 0) { sum_up++; } } offset++; } } if (sum_bj != 0) { fs = sum_jc * 1.0f / sum_bj; } return fs; } int ImgCheckAnalysisy::GetCheckResultBLob() { m_pdetlog->AddCheckstr(PrintLevel_0, "GetCheckResultBLob", "=======start"); long t1, t2, t3, t4, t5, t6, t7; t1 = CheckUtil::getcurTime(); // 获得所有的缺陷的blob 信息。 int re = GetALLBlob(); if (re != 0) { return re; } // 缺陷分类 多线程 实现。 long t11 = CheckUtil::getcurTime(); // 只进行blob分析。 if (m_pFuntion->function.f_OnlyBLob.bOpen) { m_pdetlog->AddCheckstr(PrintLevel_1, "GetCheckResultBLob", "------ f_OnlyBLob = true\n"); m_pImageAllResult->bOnlyBlob = true; } else { m_Classtask = std::make_shared(); m_Classtask->taskname = Task_Class; m_task.sendTask(m_Classtask); } // 计算blob 的其他信息,如灰阶、长度、密度等待。 re = CalBlob_Other(); if (re != 0) { return re; } long t12 = CheckUtil::getcurTime(); // 等待分类 完成。 if (m_Classtask != nullptr) { m_Classtask->waitComplate(); } // m_Classtask->waitComplate(); long t13 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, "GetCheckResultBLob", "=========== ALL time %ld waite class time %ld\n", t13 - t11, t13 - t12); // printf("=========== cls time %ld waite time %ld\n", t13 - t11, t13 - t12); BLobToDetResult(); return 0; } int ImgCheckAnalysisy::LDJudge(int nconfigtype, cv::Rect roi, float JudgeArea, int maxV, int hj, std::shared_ptr pQxlog) { int dbresult = UseDPMask(0, nconfigtype, roi, JudgeArea, maxV, hj, pQxlog); if (dbresult > 0) { return 1; } return 0; } int ImgCheckAnalysisy::UseDPMask(int L0, int nconfigtype, cv::Rect roi, float JudgeArea, int maxV, int hj, std::shared_ptr pQxlog) { if (!m_pFuntion->function.f_LDConfig.bOpen) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", "function close"); return 0; } // 要使用 DP 的结果 if (m_pFuntion->function.f_LDConfig.bUseDP) { cv::Mat DPMaskImg = m_pImageAllResult->cameraBaseResult->DP_MaskImg; pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", "Use Dp Mask"); if (DPMaskImg.empty()) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", "Error Dp Mask is empty"); return 0; } if (true && DetImgInfo_shareP->otherValue == 9) { cv::imwrite("DPMaskImgj.png", DPMaskImg); // getchar(); } bool bhave = false; { float fiou = CalImgScorl_t(m_pImageAllResult->qx_DetAIResult->AI_MaskImg(roi).clone(), DPMaskImg(roi).clone()); // IOU if (fiou > m_pFuntion->function.f_LDConfig.fDP_IOU) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", " fiou %f > %f ", fiou, m_pFuntion->function.f_LDConfig.fDP_IOU); bhave = true; // break; } else { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", " fiou %f <= %f ", fiou, m_pFuntion->function.f_LDConfig.fDP_IOU); } // m_TemCheck.AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "UseDPMask", " fiou %f < 0.1 ", fiou); } // 上电(L0)有 下电(DP)没有 if (bhave) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", " = DP "); return 0; } else { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", " != DP "); } } else { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", "No Use Dp Mask"); } bool bhave = false; if (m_pFuntion->function.f_LDConfig.bHSLD) { float aT1 = m_LD_HSConfig.minArea; float aT2 = m_LD_HSConfig.maxArea; int vT = m_LD_HSConfig.hj; if (JudgeArea >= aT1 && JudgeArea <= aT2 && hj >= vT) { bhave = true; } pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "HS LD check ", "result %s -> JudgeArea %f [%f %f] hj %d %s %d ", BOOL_TO_STR(bhave), JudgeArea, aT1, aT2, hj, BOOL_TO_ThanLess(hj > vT), vT); } else if (m_pFuntion->function.f_LDConfig.bWTBLD) { float aT1 = m_LD_WTBConfig.minArea; float aT2 = m_LD_WTBConfig.maxArea; int vT = m_LD_WTBConfig.hj; if (JudgeArea >= aT1 && JudgeArea <= aT2 && hj >= vT) { bhave = true; } pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "WTB LD check ", "result %s -> JudgeArea %f [%f %f] hj %d %s %d ", BOOL_TO_STR(bhave), JudgeArea, aT1, aT2, hj, BOOL_TO_ThanLess(hj > vT), vT); } else { float aT1 = m_LDConfig.minArea; float aT2 = m_LDConfig.maxArea; int vT = m_LDConfig.hj; if (JudgeArea >= aT1 && JudgeArea <= aT2 && hj >= vT) { bhave = true; } pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "L0 LD check ", "result %s -> JudgeArea %f [%f %f] hj %d %s %d ", BOOL_TO_STR(bhave), JudgeArea, aT1, aT2, hj, BOOL_TO_ThanLess(hj > vT), vT); } if (bhave) { return 1; } return 0; } int ImgCheckAnalysisy::UPdateLDConfig() { for (int i = 0; i < CONFIG_QX_NAME_count; i++) { if (i != CONFIG_QX_NAME_LD) { continue; } int paramIdx = m_QxInParamListIdx[i]; if (paramIdx < 0) { continue; } CheckConfig_Regions_Param *pParam = &m_pRegionAnalysisyParam->checkConfig_Regions_type[ANALYSIS_TYPE_TF].checkConfig_Regions_Param.at(paramIdx); for (int j = 0; j < pParam->useNum; j++) { if (!pParam->paramArr[j].bEnable) { continue; } m_LDConfig.minArea = pParam->paramArr[j].area; m_LDConfig.maxArea = pParam->paramArr[j].area_max; m_LDConfig.hj = pParam->paramArr[j].hj; m_LDConfig.buse = true; } } for (int i = 0; i < CONFIG_QX_NAME_count; i++) { if (i != CONFIG_QX_NAME_LD_WTB) { continue; } int paramIdx = m_QxInParamListIdx[i]; if (paramIdx < 0) { continue; } CheckConfig_Regions_Param *pParam = &m_pRegionAnalysisyParam->checkConfig_Regions_type[ANALYSIS_TYPE_TF].checkConfig_Regions_Param.at(paramIdx); for (int j = 0; j < pParam->useNum; j++) { if (!pParam->paramArr[j].bEnable) { continue; } m_LD_WTBConfig.minArea = pParam->paramArr[j].area; m_LD_WTBConfig.maxArea = pParam->paramArr[j].area_max; m_LD_WTBConfig.hj = pParam->paramArr[j].hj; m_LD_WTBConfig.buse = true; } } for (int i = 0; i < CONFIG_QX_NAME_count; i++) { if (i != CONFIG_QX_NAME_LD_HS) { continue; } int paramIdx = m_QxInParamListIdx[i]; if (paramIdx < 0) { continue; } CheckConfig_Regions_Param *pParam = &m_pRegionAnalysisyParam->checkConfig_Regions_type[ANALYSIS_TYPE_TF].checkConfig_Regions_Param.at(paramIdx); for (int j = 0; j < pParam->useNum; j++) { if (!pParam->paramArr[j].bEnable) { continue; } m_LD_HSConfig.minArea = pParam->paramArr[j].area; m_LD_HSConfig.maxArea = pParam->paramArr[j].area_max; m_LD_HSConfig.hj = pParam->paramArr[j].hj; m_LD_HSConfig.buse = true; } } return 0; } void worker(const unsigned char *img, int w, int startRow, int endRow, unsigned char *rowFlags) { for (int y = startRow; y < endRow; y++) { const unsigned char *p = img + (size_t)y * w; rowFlags[y] = 0; for (int x = 0; x < w; x++) { if (p[x] != 0) { rowFlags[y] = 1; break; } } } } int ImgCheckAnalysisy::GetALLBlob() { m_AI_Other_task->waitComplate(); std::string strBaseLog = "Blob"; m_pdetlog->AddCheckstr(PrintLevel_0, strBaseLog, "---GetALLBlob Start"); long t1 = CheckUtil::getcurTime(); int re = 0; re = GetBLob_YX(); long t2 = CheckUtil::getcurTime(); re = GetBlob_LackPol(); long t3 = CheckUtil::getcurTime(); re = GetBlob_QX(); long t4 = CheckUtil::getcurTime(); re = GetBlob_127cell(); if (blobs.blobCount > 100) { blobs.blobCount = 100; /* code */ } long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, strBaseLog, "---GetALLBlob End ;use time %ld ms yx %ld ms lack %ld ms qx %ld ms 127 %ld ms", te - t1, t2 - t1, t3 - t2, t4 - t3, te - t4); // getchar(); return 0; } int ImgCheckAnalysisy::GetBLob_YX() { if (m_pFuntion && m_pFuntion->function.f_YXDet.bOpen) { } else { return 1; } cv::Mat maskimg = m_pImageAllResult->YX_MaskImg; if (maskimg.empty()) { return 1; } // 定义腐蚀操作的内核 int kernelSize = 11; // 内核大小 cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(kernelSize, kernelSize)); // 执行腐蚀操作 cv::Mat erodedImage; cv::erode(maskimg, erodedImage, kernel); // 屏蔽框屏蔽。 if (!m_pImageAllResult->shieldImg.empty()) { std::shared_ptr pAI_Model = AI_Factory->AI_defect_YX_1; cv::Size sz; sz.width = pAI_Model->input_0.width; sz.height = pAI_Model->input_0.height; cv::Mat detmask_size; cv::resize(m_pImageAllResult->shieldImg, detmask_size, sz, 0, 0, cv::INTER_AREA); erodedImage.setTo(0, detmask_size); } cv::Mat showimg; if (DetImgInfo_shareP->bDebugsaveImg) { cv::cvtColor(erodedImage, showimg, cv::COLOR_GRAY2BGR); } // det To src float fx_src = m_pImageAllResult->detImg.cols * 1.0f / maskimg.cols; float fy_src = m_pImageAllResult->detImg.rows * 1.0f / maskimg.rows; int config_qx_type = CONFIG_QX_NAME_AD_YX; std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type]; // 轮廓检测 std::vector> contours; cv::findContours(erodedImage, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); int nresult = 0; for (size_t i = 0; i < contours.size(); ++i) { double area = cv::contourArea(contours.at(i)); double judgeArea = area * fx_src * fy_src * m_fImgage_Scale_X * m_fImgage_Scale_Y; int curresult = 0; cv::Rect roi = cv::boundingRect(contours[i]); if (DetImgInfo_shareP->bDebugsaveImg) { cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255), 2); } roi.x *= fx_src; roi.width *= fx_src; roi.y *= fy_src; roi.height *= fy_src; float len = std::sqrt(roi.width * roi.width + roi.height * roi.height); if (true) { QX_ERROR_INFO_ temerror; temerror.roi = roi; temerror.Idx = m_pDetResult->pQx_ErrorList->size(); temerror.area = area; temerror.JudgArea = judgeArea; temerror.JudgArea_second = judgeArea; temerror.energy = area * fx_src * fy_src; temerror.flen = len; temerror.nconfig_qx_type = config_qx_type; temerror.qx_name = qx_name; temerror.maxValue = 0; temerror.grayDis = 0; temerror.density = 0; temerror.fUpIou = 0; { // 添加检测区域 0 if (temerror.detRegionidxList.size() <= 0) { temerror.detRegionidxList.push_back(0); } } m_pDetResult->pQx_ErrorList->push_back(temerror); } } // 临时存图 if (DetImgInfo_shareP->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_YX_det_mask_add_shield.png", showimg); } m_pdetlog->AddCheckstr(PrintLevel_1, "GetBLob_YX", " YX NUM %ld", contours.size()); return 0; } int ImgCheckAnalysisy::GetBlob_LackPol() { if (m_pFuntion && m_pFuntion->function.f_Dectect_LackPol.bOpen) { } else { return 1; } cv::Mat maskimg = m_pImageAllResult->LcakPol_MaskImg; if (maskimg.empty()) { return 1; } cv::Mat erodedImage = maskimg; // 屏蔽框屏蔽。 if (!m_pImageAllResult->shieldImg.empty()) { std::shared_ptr pAI_Model = AI_Factory->AI_defect_LackPol; cv::Size sz; sz.width = pAI_Model->input_0.width; sz.height = pAI_Model->input_0.height; cv::Mat detmask_size; cv::resize(m_pImageAllResult->shieldImg, detmask_size, sz, 0, 0, cv::INTER_AREA); erodedImage.setTo(0, detmask_size); } cv::Mat showimg; if (DetImgInfo_shareP->bDebugsaveImg) { cv::cvtColor(erodedImage, showimg, cv::COLOR_GRAY2BGR); } int config_qx_type = CONFIG_QX_NAME_LackPOL; std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type]; // 轮廓检测 std::vector> contours; cv::findContours(erodedImage, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); int nresult = 0; // det To src float fx_src = m_pImageAllResult->detImg.cols * 1.0f / maskimg.cols; float fy_src = m_pImageAllResult->detImg.rows * 1.0f / maskimg.rows; for (size_t i = 0; i < contours.size(); ++i) { double area = cv::contourArea(contours.at(i)); double judgeArea = area * fx_src * fy_src * m_fImgage_Scale_X * m_fImgage_Scale_Y; int curresult = 0; cv::Rect roi = cv::boundingRect(contours[i]); if (DetImgInfo_shareP->bDebugsaveImg) { cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255), 2); } roi.x *= fx_src; roi.width *= fx_src; roi.y *= fy_src; roi.height *= fy_src; float len = std::sqrt(roi.width * roi.width + roi.height * roi.height); if (true) { QX_ERROR_INFO_ temerror; temerror.roi = roi; temerror.Idx = m_pDetResult->pQx_ErrorList->size(); temerror.area = area; temerror.JudgArea = judgeArea; temerror.JudgArea_second = judgeArea; temerror.energy = area * fx_src * fy_src; temerror.flen = len; temerror.nconfig_qx_type = config_qx_type; temerror.qx_name = qx_name; temerror.maxValue = 0; temerror.grayDis = 0; temerror.density = 0; temerror.fUpIou = 0; { // 添加检测区域 0 if (temerror.detRegionidxList.size() <= 0) { temerror.detRegionidxList.push_back(0); } } m_pDetResult->pQx_ErrorList->push_back(temerror); } } // 临时存图 if (DetImgInfo_shareP->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_LackPol_det_mask_add_shield.png", showimg); } m_pdetlog->AddCheckstr(PrintLevel_1, "GetBlob_LackPol", " LackPol NUM %ld", contours.size()); return 0; } int ImgCheckAnalysisy::GetBlob_QX() { std::string strBaseLog = "GetBlob_QX"; if (!m_pFuntion->function.f_BaseDet.bOpen) { return 0; } std::shared_ptr pDetAIResult = m_pImageAllResult->qx_DetAIResult; cv::Mat maskimg = pDetAIResult->AI_MaskImg; if (maskimg.empty()) { return 1; } unsigned char *imgBlobHFlagData = pDetAIResult->blobDetParam->imgBlobHFlagData; if (imgBlobHFlagData == NULL) { return 1; } unsigned char *pGrayErrordata = (unsigned char *)maskimg.data; int width = maskimg.cols; int height = maskimg.rows; long t1 = CheckUtil::getcurTime(); ERROR_DOTS_BLOBS blobs_all; memset(&blobs_all, 0x00, sizeof(ERROR_DOTS_BLOBS)); ERROR_DOTS_BLOBS blobs_v1; memset(&blobs_v1, 0x00, sizeof(ERROR_DOTS_BLOBS)); ERROR_DOTS_BLOBS blobs_big; memset(&blobs_big, 0x00, sizeof(ERROR_DOTS_BLOBS)); ERROR_DOTS_BLOBS blobs_big_2; memset(&blobs_big_2, 0x00, sizeof(ERROR_DOTS_BLOBS)); GetBlobs_oneLabe(&blobs_v1, pGrayErrordata, imgBlobHFlagData, width, height, 15); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob 1 num %d", blobs_v1.blobCount); if (blobs_v1.srcBlobCount >= _MAX_ERROR_DOT_BLOB) { GetBlobs_oneLabe(&blobs_big, pGrayErrordata, m_pImageAllResult->qx_DetAIResult->blobDetParam->imgBlobHFlagData, width, height, 200); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob 2 num %d", blobs_big.blobCount); if (blobs_big.srcBlobCount >= _MAX_ERROR_DOT_BLOB) { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob 3 num %d", blobs_big_2.blobCount); GetBlobs_oneLabe(&blobs_big_2, pGrayErrordata, m_pImageAllResult->qx_DetAIResult->blobDetParam->imgBlobHFlagData, width, height, 500); } } long t2 = CheckUtil::getcurTime(); PushBlob(&blobs_all, &blobs_big_2); PushBlob(&blobs_all, &blobs_big); PushBlob(&blobs_all, &blobs_v1); PushBlob(&blobs, &blobs_all); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob ALL num %d", blobs_all.blobCount); if (DetImgInfo_shareP->bDebugsaveImg) { int font_face = cv::FONT_HERSHEY_SIMPLEX; double font_scale = 0.5; int thickness = 1; m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "Save Tem Img"); cv::Mat tm; cv::cvtColor(maskimg, tm, cv::COLOR_GRAY2RGB); // 彩色 可选项 for (int i = 0; i < blobs_all.blobCount; i++) { cv::Rect roi; roi.x = blobs_all.blobTab[i].minx; roi.y = blobs_all.blobTab[i].miny; roi.width = blobs_all.blobTab[i].maxx - blobs_all.blobTab[i].minx + 1; roi.height = blobs_all.blobTab[i].maxy - blobs_all.blobTab[i].miny + 1; if (blobs_all.blobTab[i].ErrType == 0) { cv::rectangle(tm, roi, cv::Scalar(0, 0, 255)); } else { cv::rectangle(tm, roi, cv::Scalar(0, 255, 255)); } char buffer[128]; sprintf(buffer, " type:%d m %0.1f", blobs.blobTab[i].ErrType, blobs.blobTab[i].density); std::string text = buffer; cv::Point origin = cv::Point(roi.x, roi.y); cv::putText(tm, text, origin, font_face, font_scale, cv::Scalar(0, 255, 0), thickness, 1, 0); // printf("type: %d %d %d %d %d %d %d\n", blobs.blobTab[i].ErrType, blobs.blobTab[i].area, blobs.blobTab[i].energy, roi.x, roi.y, roi.width, roi.height); } cv::imwrite(m_strCurDetCamChannel + "_qx_image_resize_blob.png", tm); } long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "image Blob Analysis End use time %ld blob %ld ms", te - t1, t2 - t1); return 0; } int ImgCheckAnalysisy::GetBlob_127cell() { std::string strBaseLog = "GetBlob_127cell"; if (m_pFuntion && m_pFuntion->function.f_Det127Cell.bOpen) { } else { // 未开启检测 return 0; } std::shared_ptr pDetAIResult = m_pImageAllResult->cell127_DetAIResult; cv::Mat maskimg = pDetAIResult->AI_MaskImg; if (maskimg.empty()) { return 1; } unsigned char *imgBlobHFlagData = pDetAIResult->blobDetParam->imgBlobHFlagData; if (imgBlobHFlagData == NULL) { return 1; } unsigned char *pGrayErrordata = (unsigned char *)maskimg.data; int width = maskimg.cols; int height = maskimg.rows; long t1 = CheckUtil::getcurTime(); ERROR_DOTS_BLOBS blobs_all; memset(&blobs_all, 0x00, sizeof(ERROR_DOTS_BLOBS)); ERROR_DOTS_BLOBS blobs_v1; memset(&blobs_v1, 0x00, sizeof(ERROR_DOTS_BLOBS)); ERROR_DOTS_BLOBS blobs_big; memset(&blobs_big, 0x00, sizeof(ERROR_DOTS_BLOBS)); ERROR_DOTS_BLOBS blobs_big_2; memset(&blobs_big_2, 0x00, sizeof(ERROR_DOTS_BLOBS)); GetBlobs_oneLabe(&blobs_v1, pGrayErrordata, imgBlobHFlagData, width, height, 15); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob 1 num %d", blobs_v1.blobCount); if (blobs_v1.srcBlobCount >= _MAX_ERROR_DOT_BLOB) { GetBlobs_oneLabe(&blobs_big, pGrayErrordata, m_pImageAllResult->qx_DetAIResult->blobDetParam->imgBlobHFlagData, width, height, 200); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob 2 num %d", blobs_big.blobCount); if (blobs_big.srcBlobCount >= _MAX_ERROR_DOT_BLOB) { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob 3 num %d", blobs_big_2.blobCount); GetBlobs_oneLabe(&blobs_big_2, pGrayErrordata, m_pImageAllResult->qx_DetAIResult->blobDetParam->imgBlobHFlagData, width, height, 500); } } long t2 = CheckUtil::getcurTime(); PushBlob(&blobs_all, &blobs_big_2); PushBlob(&blobs_all, &blobs_big); PushBlob(&blobs_all, &blobs_v1); for (int i = 0; i < blobs_all.blobCount; i++) { blobs_all.blobTab[i].ErrType = CONFIG_QX_NAME_white_Cell; } PushBlob(&blobs, &blobs_all); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "blob ALL num %d", blobs_all.blobCount); if (DetImgInfo_shareP->bDebugsaveImg) { int font_face = cv::FONT_HERSHEY_SIMPLEX; double font_scale = 0.5; int thickness = 1; m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "Save Tem Img"); cv::Mat tm; cv::cvtColor(maskimg, tm, cv::COLOR_GRAY2RGB); // 彩色 可选项 for (int i = 0; i < blobs_all.blobCount; i++) { cv::Rect roi; roi.x = blobs_all.blobTab[i].minx; roi.y = blobs_all.blobTab[i].miny; roi.width = blobs_all.blobTab[i].maxx - blobs_all.blobTab[i].minx + 1; roi.height = blobs_all.blobTab[i].maxy - blobs_all.blobTab[i].miny + 1; if (blobs_all.blobTab[i].ErrType == 0) { cv::rectangle(tm, roi, cv::Scalar(0, 0, 255)); } else { cv::rectangle(tm, roi, cv::Scalar(0, 255, 255)); } char buffer[128]; sprintf(buffer, " type:%d m %0.1f", blobs.blobTab[i].ErrType, blobs.blobTab[i].density); std::string text = buffer; cv::Point origin = cv::Point(roi.x, roi.y); cv::putText(tm, text, origin, font_face, font_scale, cv::Scalar(0, 255, 0), thickness, 1, 0); // printf("type: %d %d %d %d %d %d %d\n", blobs.blobTab[i].ErrType, blobs.blobTab[i].area, blobs.blobTab[i].energy, roi.x, roi.y, roi.width, roi.height); } cv::imwrite(m_strCurDetCamChannel + "_127cell_image_resize_blob.png", tm); } long te = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "image Blob Analysis End use time %ld blob %ld ms", te - t1, t2 - t1); return 0; } int ImgCheckAnalysisy::AIMaskDet() { m_pdetlog->AddCheckstr(PrintLevel_0, "AIMaskDet", "=======start"); std::shared_ptr blobDetParam; // AI QX 检测 while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (!m_pImageAllResult->qx_DetAIResult) { // 等待初始化 continue; } blobDetParam = m_pImageAllResult->qx_DetAIResult->blobDetParam; std::shared_ptr AImaskResult; { std::lock_guard lock(blobDetParam->mtx_AIMaskImgBLobQueue); if (blobDetParam->AIMaskImgBLobQueue.size() > 0) { AImaskResult = std::move(blobDetParam->AIMaskImgBLobQueue.front()); blobDetParam->AIMaskImgBLobQueue.pop(); // printf("size ============== %ld\n", m_AIMaskImgBLobQueue.size()); } } // 有AI mask 的结果 if (AImaskResult) { // static int ss = 0; cv::Mat outimg = AImaskResult->AI_mask; // cv::imwrite(std::to_string(ss++) + ".png", outimg); unsigned char *pGrayErrordata = (unsigned char *)outimg.data; int width = outimg.cols; int height = outimg.rows; int start_Y = AImaskResult->roi.y; if (cv::countNonZero(outimg != 0) != 0) { // #pragma omp parallel for for (int y = 0; y < height; y++) { if ((y + start_Y) < blobDetParam->ndatalen && blobDetParam->imgBlobHFlagData[y + start_Y] == 0) { unsigned char *p = pGrayErrordata + y * width; for (int x = 0; x < width; x++) { if (p[x] != 0) { // printf("===========qx_DetAIResult======m_ImgBlobHFlagData %d===%d = %d=======0 \n", blobDetParam->ndatalen, y + start_Y, outimg.rows); blobDetParam->imgBlobHFlagData[y + start_Y] = 1; break; } } } } } } else { /* code */ if (m_AItask->isComplate()) { break; } } } m_pdetlog->AddCheckstr(PrintLevel_1, "AIMaskDet", "=======qx_DetAIResult end"); // 127 cell 检测 while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (!m_pImageAllResult->cell127_DetAIResult) { // 等待初始化 continue; } blobDetParam = m_pImageAllResult->cell127_DetAIResult->blobDetParam; std::shared_ptr AImaskResult; { std::lock_guard lock(blobDetParam->mtx_AIMaskImgBLobQueue); if (blobDetParam->AIMaskImgBLobQueue.size() > 0) { AImaskResult = std::move(blobDetParam->AIMaskImgBLobQueue.front()); blobDetParam->AIMaskImgBLobQueue.pop(); // printf("size ============== %ld\n", m_AIMaskImgBLobQueue.size()); } } // 有AI mask 的结果 if (AImaskResult) { // static int ss = 0; cv::Mat outimg = AImaskResult->AI_mask; // cv::imwrite(std::to_string(ss++) + ".png", outimg); unsigned char *pGrayErrordata = (unsigned char *)outimg.data; int width = outimg.cols; int height = outimg.rows; int start_Y = AImaskResult->roi.y; if (cv::countNonZero(outimg != 0) != 0) { // #pragma omp parallel for for (int y = 0; y < height; y++) { if ((y + start_Y) < blobDetParam->ndatalen && blobDetParam->imgBlobHFlagData[y + start_Y] == 0) { unsigned char *p = pGrayErrordata + y * width; for (int x = 0; x < width; x++) { if (p[x] != 0) { // printf("===============cell127_DetAIResult ====m_ImgBlobHFlagData %d===%d = %d=======0 \n", blobDetParam->ndatalen, y + start_Y, outimg.rows); blobDetParam->imgBlobHFlagData[y + start_Y] = 1; break; } } } } } } else { /* code */ if (m_AItask->isComplate()) { break; } } } m_pdetlog->AddCheckstr(PrintLevel_1, "AIMaskDet", "=======cell127_DetAIResult end"); m_AItask->waitComplate(); int rec = m_AItask->nresult; m_pdetlog->AddCheckstr(PrintLevel_1, "AIMaskDet", "=======m_AItask waitComplate m_AItask->nresult %d", rec); if (rec != CHECK_OK) { return rec; } return 0; } int ImgCheckAnalysisy::Contours() { // std::string strBaseLog = "Contours"; // // m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, "Contours Start"); // cv::Mat detimg; // { // // 膨胀 // cv::Mat se = getStructuringElement(0, Size(5, 5)); // 构造矩形结构元素 // cv::dilate(m_pdetlog->temImgList[TEM_IMG_IDX_AImask], detimg, se); // } // std::vector> contours; // std::vector hierarchy; // cv::findContours(detimg, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); // 只找最外层轮廓 // // cv::cvtColor(m_pdetlog->temImgList[TEM_IMG_IDX_SrcCrop], m_pdetlog->temImgList[TEM_IMG_IDX_DrawSrc], cv::COLOR_GRAY2BGR); // for (int i = 0; i < contours.size(); ++i) // { // 绘制所有轮廓 // cv::drawContours(m_pdetlog->temImgList[TEM_IMG_IDX_DrawSrc], contours, i, cv::Scalar(255, 0, 255)); // thickness为-1时为填充整个轮廓 // } // float fx = m_pdetlog->temImgList[TEM_IMG_IDX_Result].cols * 1.0f / m_pdetlog->temImgList[TEM_IMG_IDX_SrcCrop].cols; // float fy = m_pdetlog->temImgList[TEM_IMG_IDX_Result].rows * 1.0f / m_pdetlog->temImgList[TEM_IMG_IDX_SrcCrop].rows; // for (int i = 0; i < contours.size(); ++i) // { // for (int j = 0; j < contours.at(i).size(); ++j) // { // contours.at(i).at(j).x *= fx; // contours.at(i).at(j).y *= fy; // } // } // // cv::cvtColor(m_pdetlog->temImgList[TEM_IMG_IDX_Result], m_pdetlog->temImgList[TEM_IMG_IDX_Result], cv::COLOR_GRAY2BGR); // for (int i = 0; i < contours.size(); ++i) // { // 绘制所有轮廓 // cv::drawContours(m_pdetlog->temImgList[TEM_IMG_IDX_Result], contours, i, cv::Scalar(255, 0, 255)); // thickness为-1时为填充整个轮廓 // } // cv::imwrite("TEM_IMG_IDX_Result.png", m_pdetlog->temImgList[TEM_IMG_IDX_Result]); // cv::imwrite("deeeee.png", m_pdetlog->temImgList[TEM_IMG_IDX_Drawmask]); // getchar(); // m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, "Contours End"); return 0; } int ImgCheckAnalysisy::CheckImgInit() { // 1、初始化 m_pDetResult->pQx_ErrorList = std::make_shared>(); m_pdetlog->Init(); m_pdetlog->addLogLevel = DET_LOG_LEVEL_3; memset(&blobs, 0, sizeof(ERROR_DOTS_BLOBS)); m_nCheckResultErrorCode = 0; m_Draw_qxImageResult.erase(m_Draw_qxImageResult.begin(), m_Draw_qxImageResult.end()); m_DetRoiList.Init(); return 0; } int ImgCheckAnalysisy::ConfigCheck(cv::Mat img) { m_pdetlog->AddCheckstr(PrintLevel_0, "start", "Config Check"); int re = CHECK_OK; if (img.empty()) { m_nErrorCode = CHECK_ERROR_CheckImg_Empty; m_pdetlog->AddCheckstr(PrintLevel_1, "Error", "check Img empty"); return m_nErrorCode; } // if (m_pCommonAnalysisyConfig->regionConfigArr.size() <= 0) // { // m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Error", "regionConfig Num = 0"); // m_nErrorCode = CHECK_ERROR_Config_Value; // return m_nErrorCode; // } m_pdetlog->AddCheckstr(PrintLevel_0, "Succ", "Config Check Succ"); return re; } int ImgCheckAnalysisy::AI_Detect_Thread() { std::string strBaseLog = "AI_Detect"; m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, "****** AI_Detect Start"); long t1, t3; t1 = CheckUtil::getcurTime(); cv::Mat AI_detImage = m_pImageAllResult->AI_detImg; std::shared_ptr pAI_Model = AI_Factory->AI_defect_NF; int re = CreatAIDetSmallRoi(AI_detImage, pAI_Model, SmallRoiList); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, "error small roi。AI_Detect End"); return 1; } // 临时存图 if (DetImgInfo_shareP->bDebugsaveImg) { cv::Mat imshow; if (AI_detImage.channels() == 1) { cv::cvtColor(AI_detImage, imshow, cv::COLOR_GRAY2RGB); // 彩色 可选项 } else { imshow = AI_detImage.clone(); } for (int i = 0; i < SmallRoiList.size(); i++) { cv::rectangle(imshow, SmallRoiList.at(i), cv::Scalar(0, 0, 255), 3); } cv::imwrite(m_strCurDetCamChannel + "_AI_Det_ROI.jpg", imshow); } // 缺陷检测 re = AI_Detect_QX(); // 127cell re = AI_Detect_127Cell(); t3 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, "****** AI_Detect End; AI Run Time: sum %ld", t3 - t1); // getchar(); return 0; } int ImgCheckAnalysisy::AI_Other_Det_Thread() { std::string strBaseLog = "AI_Other_Det"; m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, ">>>>> AI_Detect Start"); long t1, t3; t1 = CheckUtil::getcurTime(); // 检测分析 1、先进行异显检测如果,结果是异显,则不进行后续检测判断 int rec = AI_Det_YX(m_pImageAllResult->detImg); // 缺失 POL检测 rec = Detect_LackPol(m_pImageAllResult->detImg); t3 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, strBaseLog, ">>>>> AI_Detect End; AI Run Time: sum %ld", t3 - t1); // getchar(); return 0; } int ImgCheckAnalysisy::AI_Detect_QX() { std::string strBaseLog = "AI_Detect_QX"; m_pImageAllResult->qx_DetAIResult = std::make_shared(); // 未开启检测 if (!m_pFuntion->function.f_BaseDet.bOpen) { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " base detect close"); return 0; } long ts, t2, te; ts = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "============= Start"); std::shared_ptr pDetAIResult = m_pImageAllResult->qx_DetAIResult; int re = 0; cv::Mat AI_detImage = m_pImageAllResult->AI_detImg; // 确定检测模型 std::shared_ptr pAI_Model; if (m_pFuntion->function.f_BaseDet.strAIMode == "UP") { pAI_Model = AI_Factory->AI_defect_UP; m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "=======model use UP"); } else { if (m_pFuntion->function.f_BaseDet.strAIMode == "WandB") { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "=======model use WandB"); pAI_Model = AI_Factory->AI_defect_Type2; } else if (m_pFuntion->function.f_BaseDet.strAIMode == "Chess") { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "=======model use Chess"); pAI_Model = AI_Factory->AI_defect_Chess; } else if (m_pFuntion->function.f_BaseDet.strAIMode == "RGB-HGRAY") { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "=======model use RE_RGBHGRAY"); pAI_Model = AI_Factory->AI_defect_RE_RGBHGRAY; } else { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "=======model use base"); pAI_Model = AI_Factory->AI_defect_NF; } } int AIInputImg_width = pAI_Model->input_0.width; int AIInputImg_height = pAI_Model->input_0.height; int AIOutputImg_width = pAI_Model->output_0.width; int AIOutputImg_height = pAI_Model->output_0.height; pDetAIResult->InitBLobHData(AI_detImage.rows); // 是否需要 resize到输入图大小进行后续处理。 bool bResizeToSrc = false; if (AIOutputImg_width != AIInputImg_width || AIOutputImg_height != AIInputImg_height) { bResizeToSrc = true; } // 如果尺寸不合适,要重新计算 smll roi.一般情况来说,small roi 都是相同的对不同的AI 模型。在模型设计时要做到统一,降低调用复杂度。 if (SmallRoiList.size() > 0) { int roi_width = SmallRoiList.at(0).width; int roi_height = SmallRoiList.at(0).height; if (roi_width != AIInputImg_width || roi_height != AIInputImg_height) { int re = CreatAIDetSmallRoi(AI_detImage, pAI_Model, SmallRoiList); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "error small roi"); return 1; } } } const int totalTasks = SmallRoiList.size(); if (totalTasks <= 0) { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "error small roi = 0"); return 0; } int submitted = 0; int completed = 0; cv::Size src_sz; src_sz.width = AIInputImg_width; src_sz.height = AIInputImg_height; pDetAIResult->AI_MaskImg = cv::Mat::zeros(AI_detImage.size(), CV_8UC1); cv::Mat shieldImg = m_pImageAllResult->AI_shieldImg; cv::Mat AIresultMask = pDetAIResult->AI_MaskImg; t2 = CheckUtil::getcurTime(); while (completed < totalTasks) { // 如果任务还没提交完,且当前处理任务数 < 2,提交新任务 if (submitted < totalTasks && runner->GetProcessingCount() < 10) { std::shared_ptr task = std::make_shared(); task->id = completed; task->roi = SmallRoiList.at(submitted); task->input = AI_detImage(task->roi).clone(); task->output = std::make_shared(); task->engine = pAI_Model; if (submitted >= det_SmallImgNum) { task->userflag = 9; } runner->SubmitTask(task); submitted++; } // 尝试取结果 std::shared_ptr result; if (runner->PopResult(result)) { cv::Mat &outimg = *(result->output); if (!outimg.empty()) { cv::Mat AIresult; if (bResizeToSrc) { // 1、 resize 到原始大小。 cv::resize(outimg, AIresult, src_sz, 0, 0, 0); } else { AIresult = outimg; } cv::Rect srcsize_roi = result->roi; // 2、 屏蔽 缺陷 AIresult.setTo(0, shieldImg(result->roi)); // 如果是字符区域,则 全部替换 if (result->userflag == 9) { AIresult.copyTo(AIresultMask(result->roi)); } else { AIresult.copyTo(AIresultMask(result->roi), AIresult); } { std::shared_ptr temAIresult = std::make_shared(); temAIresult->roi = result->roi; temAIresult->AI_inImg = result->input; temAIresult->AI_mask = outimg; pDetAIResult->AI_Qx_MaskList.push_back(temAIresult); } { std::shared_ptr temAIresult = std::make_shared(); temAIresult->roi = result->roi; temAIresult->AI_mask = AIresult; { std::lock_guard lock(pDetAIResult->blobDetParam->mtx_AIMaskImgBLobQueue); pDetAIResult->blobDetParam->AIMaskImgBLobQueue.push(temAIresult); } } } completed++; } else { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } te = CheckUtil::getcurTime(); float mean_AI = (te - t2) / SmallRoiList.size(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "============= End; AI Run Time: sum %ld pre %ld Run %ld mean One Small Img %f", te - ts, t2 - ts, te - t2, mean_AI); // 临时存图 if (DetImgInfo_shareP->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_AI_QX_mask.png", AIresultMask); } return 0; } int ImgCheckAnalysisy::AI_Detect_127Cell() { std::string strBaseLog = "AI_Detect_127Cell"; m_pImageAllResult->cell127_DetAIResult = std::make_shared(); if (m_pFuntion && m_pFuntion->function.f_Det127Cell.bOpen) { } else { // 未开启检测 m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " f_Det127Cell close"); return 0; } long ts, t2, te; ts = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "============= Start"); std::shared_ptr pDetAIResult = m_pImageAllResult->cell127_DetAIResult; cv::Mat AI_detImage = m_pImageAllResult->AI_detImg; std::shared_ptr pAI_Model = AI_Factory->AI_defect_127Cell; int AIInputImg_width = pAI_Model->input_0.width; int AIInputImg_height = pAI_Model->input_0.height; int AIOutputImg_width = pAI_Model->output_0.width; int AIOutputImg_height = pAI_Model->output_0.height; pDetAIResult->InitBLobHData(AI_detImage.rows); // 是否需要 resize到输入图大小进行后续处理。 bool bResizeToSrc = false; if (AIOutputImg_width != AIInputImg_width || AIOutputImg_height != AIInputImg_height) { bResizeToSrc = true; } // 如果尺寸不合适,要重新计算 smll roi.一般情况来说,small roi 都是相同的对不同的AI 模型。在模型设计时要做到统一,降低调用复杂度。 if (SmallRoiList.size() > 0) { int roi_width = SmallRoiList.at(0).width; int roi_height = SmallRoiList.at(0).height; if (roi_width != AIInputImg_width || roi_height != AIInputImg_height) { int re = CreatAIDetSmallRoi(AI_detImage, pAI_Model, SmallRoiList); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "error small roi"); return 1; } } } const int totalTasks = SmallRoiList.size(); if (totalTasks <= 0) { m_pdetlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, strBaseLog, "error small roi = 0"); return 0; } int submitted = 0; int completed = 0; cv::Size src_sz; src_sz.width = AIInputImg_width; src_sz.height = AIInputImg_height; pDetAIResult->AI_MaskImg = cv::Mat::zeros(AI_detImage.size(), CV_8UC1); cv::Mat shieldImg = m_pImageAllResult->AI_shieldImg; cv::Mat AIresultMask = pDetAIResult->AI_MaskImg; t2 = CheckUtil::getcurTime(); while (completed < totalTasks) { // 如果任务还没提交完,且当前处理任务数 < 2,提交新任务 if (submitted < totalTasks && runner->GetProcessingCount() < 10) { std::shared_ptr task = std::make_shared(); task->id = completed; task->roi = SmallRoiList.at(submitted); task->input = AI_detImage(task->roi).clone(); task->output = std::make_shared(); task->engine = pAI_Model; if (submitted >= det_SmallImgNum) { task->userflag = 9; } runner->SubmitTask(task); submitted++; } // 尝试取结果 std::shared_ptr result; if (runner->PopResult(result)) { cv::Mat &outimg = *(result->output); if (!outimg.empty()) { cv::Mat AIresult; if (bResizeToSrc) { // 1、 resize 到原始大小。 cv::resize(outimg, AIresult, src_sz, 0, 0, 0); } else { AIresult = outimg; } cv::Rect srcsize_roi = result->roi; // 2、 屏蔽 缺陷 AIresult.setTo(0, shieldImg(result->roi)); // 如果是字符区域,则 全部替换 if (result->userflag == 9) { AIresult.copyTo(AIresultMask(result->roi)); } else { AIresult.copyTo(AIresultMask(result->roi), AIresult); } { std::shared_ptr temAIresult = std::make_shared(); temAIresult->roi = result->roi; temAIresult->AI_inImg = result->input; temAIresult->AI_mask = outimg; pDetAIResult->AI_Qx_MaskList.push_back(temAIresult); } { std::shared_ptr temAIresult = std::make_shared(); temAIresult->roi = result->roi; temAIresult->AI_mask = AIresult; { std::lock_guard lock(pDetAIResult->blobDetParam->mtx_AIMaskImgBLobQueue); pDetAIResult->blobDetParam->AIMaskImgBLobQueue.push(temAIresult); } } } completed++; } else { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } // 临时存图 if (DetImgInfo_shareP->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_AI_127cell_mask.png", AIresultMask); } te = CheckUtil::getcurTime(); float mean_AI = (te - t2) / SmallRoiList.size(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, "============= End; AI Run Time: sum %ld pre %ld Run %ld mean One Small Img %f", te - ts, t2 - ts, te - t2, mean_AI); return 0; } int ImgCheckAnalysisy::AI_QX_Class_Thread() { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "QX_Class", " Start"); float fs_x = m_fImgage_Scale_X; float fs_y = m_fImgage_Scale_Y; for (int i = 0; i < blobs.blobCount; i++) { if (blobs.blobTab[i].ErrType == CONFIG_QX_NAME_white_Cell || blobs.blobTab[i].ErrType == CONFIG_QX_NAME_black_Cell) { } else { cv::Rect roi; roi.x = blobs.blobTab[i].minx; roi.y = blobs.blobTab[i].miny; roi.width = blobs.blobTab[i].maxx - blobs.blobTab[i].minx + 1; roi.height = blobs.blobTab[i].maxy - blobs.blobTab[i].miny + 1; float JudgArea = blobs.blobTab[i].area * fs_x * fs_y; float fmaxScore = 0; int config_qx_type = 0; config_qx_type = AI_Classify_New(m_pImageAllResult->AI_detImg, roi, JudgArea, &fmaxScore); // config_qx_type = AI_Classify(sizeimg, roi, JudgArea, &fmaxScore); // 方格线判断 if (config_qx_type == CONFIG_QX_NAME_Y_line || config_qx_type == CONFIG_QX_NAME_X_line) { bool bchange = false; float fwh = roi.width * 1.0f / roi.height; if (roi.height > roi.width) { fwh = roi.height * 1.0f / roi.width; } else { fwh = roi.width * 1.0f / roi.height; } if (fwh < 7) { bchange = true; } if (bchange) { config_qx_type = CONFIG_QX_NAME_Fangge; } m_pdetlog->AddCheckstr(PrintLevel_3, " Y line to fangge line ", "change = %d width %f < 7", bchange, fwh); } blobs.blobTab[i].ErrType = config_qx_type; // m_pdetlog->AddCheckstr(PrintLevel_3, " AI_QX_Class_Thread ", "qx %d ErrType %d ", i, config_qx_type); } } return 0; } int ImgCheckAnalysisy::ThreadTask(int nId) { while (!m_bExit) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 等待是否有任务 std::shared_ptr task = m_task.GetTask(); // 把任务发送给对应的任务处理函数进行处理 switch (task->taskname) { case Task_AI: TaskFun_AIDet(task); break; case Task_AI_Other: TaskFun_AI_Other(task); break; case Task_Class: TaskFun_QxClass(task); break; default: break; } } return 0; } int ImgCheckAnalysisy::ResizeImg() { cv::Size sz; sz.width = RESIZE_IMAGE_WIDTH; float fw = RESIZE_IMAGE_WIDTH * 1.0f / m_pImageAllResult->detImg.cols; sz.height = int(m_pImageAllResult->detImg.rows * fw); cv::resize(m_pImageAllResult->detImg, m_pImageAllResult->resultImg, sz); // 需要绘制屏蔽区 if ((m_pBasicConfig && m_pBasicConfig->bDrawShieldRoi) || (m_pFuntion && m_pFuntion->function.f_ShieldRegion.bOpen && m_pFuntion->function.f_ShieldRegion.bDraw)) { m_pdetlog->AddCheckstr(PrintLevel_1, "ResizeImg", "DrawShieldR param is open"); cv::Mat shieldImg = m_pImageAllResult->shieldImg; cv::Mat sizeshieldimg; if (!shieldImg.empty()) { cv::resize(shieldImg, sizeshieldimg, sz); sizeshieldimg *= 0.2; m_pImageAllResult->resultImg += sizeshieldimg; } } if (m_pImageAllResult->resultImg.channels() == 1) { cv::cvtColor(m_pImageAllResult->resultImg, m_pImageAllResult->resultImg, cv::COLOR_GRAY2BGR); } m_CheckResult_shareP->resultimg = m_pImageAllResult->resultImg; m_pdetlog->AddCheckstr(PrintLevel_1, "ResizeImg", "showImg size [w %d,h %d]-> show img [w %d,h %d] ", m_CutRoi.width, m_CutRoi.height, sz.width, sz.height); return 0; } void ImgCheckAnalysisy::TaskFun_AIDet(std::shared_ptr task) { task->SetStatus(TaskStep_run); long t1, t2; // AI 推理生成 { t1 = CheckUtil::getcurTime(); int rec = AI_Detect_Thread(); t2 = CheckUtil::getcurTime(); task->nresult = rec; } task->SetStatus(TaskStep_compate); } void ImgCheckAnalysisy::TaskFun_AI_Other(std::shared_ptr task) { task->SetStatus(TaskStep_run); long t1, t2; // AI 推理生成 { t1 = CheckUtil::getcurTime(); int rec = AI_Other_Det_Thread(); t2 = CheckUtil::getcurTime(); task->nresult = rec; } task->SetStatus(TaskStep_compate); } void ImgCheckAnalysisy::TaskFun_QxClass(std::shared_ptr task) { task->SetStatus(TaskStep_run); long t1, t2; // AI 推理生成 { t1 = CheckUtil::getcurTime(); int rec = AI_QX_Class_Thread(); t2 = CheckUtil::getcurTime(); task->nresult = rec; } task->SetStatus(TaskStep_compate); } int ImgCheckAnalysisy::Update_DetRoiList() { m_pdetlog->AddCheckstr(PrintLevel_0, "Update_DetRoiList", "=======start:"); float fx = m_pImageAllResult->fscale_detToresult_x; float fy = m_pImageAllResult->fscale_detToresult_y; int num = 0; cv::Rect offsetroi = m_Crop_Roi_paramImg; // if (m_pEdge_Align_Result && m_pEdge_Align_Result->buseOfft) // { // for (const auto ®ion : m_pCommonAnalysisyConfig->regionConfigArr) // { // if (m_pEdge_Align_Result->H.empty()) // { // m_DetRoiList.Update_1(region.basicInfo.pointArry, offsetroi, m_pEdge_Align_Result->offt_x, m_pEdge_Align_Result->offt_y, fx, fy); // } // else // { // m_DetRoiList.Update_Marit(region.basicInfo.pointArry, offsetroi, m_pEdge_Align_Result->H, fx, fy); // } // // m_DetRoiList.Update_1(region.basicInfo.pointArry, offsetroi, m_pEdge_Align_Result->offt_x, m_pEdge_Align_Result->offt_y, fx, fy); // } // } // else { for (const auto ®ion : m_pCommonAnalysisyConfig->regionConfigArr) { m_DetRoiList.Update(region.basicInfo.pointArry, m_Crop_Roi_paramImg, fx, fy); } } m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "info", "roiList_Src roi num %ld", m_DetRoiList.roiList_Src.size()); // m_DetRoiList.print("m_DetRoiList"); return 0; } int ImgCheckAnalysisy::Edge_Det() { std::string strBaseLog = "Edge_Det"; // return 0; // if (m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList) // { // m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " error pEdgeDet_roiList %ld", // m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList->size()); // } // else // { // m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " error pEdgeDet_roiList 111"); // } if (!m_pFuntion->function.f_BaseDet.bOpen) { return 0; } if (m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList && m_pFuntion && m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList->size() > 0) { } else { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " error pEdgeDet_roiList"); return 1; } if (!m_pFuntion->function.f_dege_Det.bOpen) { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " param colse "); return 1; } long t1 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " Start EdgeDet_roiList %ld param usetype = %d ImageDet_shareP->ninstruct %d", m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList->size(), m_pFuntion->function.f_dege_Det.type, m_pImageAllResult->cameraBaseResult->pEdgeDetResult->ninstruct); AI_Edge_QX_Det::DetConfig detconfig; detconfig.pEdgeDet_roiList = m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList; detconfig.pdege_Det_config = &m_pFuntion->function.f_dege_Det; detconfig.strCamChannel = m_CheckResult_shareP->in_shareImage->strCameraName + m_CheckResult_shareP->in_shareImage->strChannel; detconfig.CutRoi = m_CutRoi; detconfig.ninstruct = m_CheckResult_shareP->in_shareImage->ninstruct; // cv::Mat temMask = cv::Mat::zeros(m_TemCheck.temImgList[TEM_IMG_IDX_AImask].size(), CV_8UC1); if (m_pFuntion->function.f_dege_Det.bOpen) { if (m_pFuntion->function.f_dege_Det.bdetUse) { m_AIEdge_QX_Det.Detect(m_CheckResult_shareP->in_shareImage->img, m_pImageAllResult->qx_DetAIResult->AI_MaskImg, &detconfig, m_pdetlog); } else { cv::Mat temmask = m_pImageAllResult->qx_DetAIResult->AI_MaskImg.clone(); m_AIEdge_QX_Det.Detect(m_CheckResult_shareP->in_shareImage->img, temmask, &detconfig, m_pdetlog); // m_CheckResult_shareP->resultMaskImg = temmask.clone(); } } long t2 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, strBaseLog, " End use time %ld ", t2 - t1); return 0; } int ImgCheckAnalysisy::DrawResult_Step_1() { m_pdetlog->AddCheckstr(PrintLevel_0, "DrawResult_Step_1", "=======start"); // std::cout << m_pBasicConfig->bDrawPreRoi << std::endl; if (m_pBasicConfig->bDrawPreRoi) { int n = 0; // std::cout << m_DetRoiList.roiList_Show.size() << std::endl; for (const auto &polygon : m_DetRoiList.roiList_Show) { // n++; // if (n == 1) // { // continue; // } // std::cout << polygon << std::endl; // 绘制多边形的边界(不填充),使用绿色线条,线宽为2 cv::polylines(m_CheckResult_shareP->resultimg, polygon, true, cv::Scalar(128, 255, 0), 1); // true表示闭合多边形 } // cv::imwrite(DetImgInfo_shareP->strChannel + "roi_src.png", m_pdetlog->temImgList[TEM_IMG_IDX_DrawSrc]); // cv::imwrite(DetImgInfo_shareP->strChannel + "roi_ss.png", m_pdetlog->temImgList[TEM_IMG_IDX_Result]); // getchar(); } float fs_resize_x = m_pImageAllResult->resultImg.cols * 1.0f / m_pImageAllResult->detImg.cols; float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows; // 绘制对齐 Align_Result *pAlignResult = &m_pImageAllResult->cameraBaseResult->pEdgeDetResult->m_align_Result; if (pAlignResult && pAlignResult->bDet && pAlignResult->bDraw) { std::vector points; for (auto point : pAlignResult->feature_PointList_DetImg) { cv::Point p; p.x = point.x * fs_resize_x; p.y = point.y * fs_resize_y; points.push_back(p); } cv::polylines(m_CheckResult_shareP->resultimg, points, true, cv::Scalar(255, 255, 0), 2); // cv::Rect droi = ImageDet_shareP->alignResult.Crop_Roi_DetImg; // droi.x = 0; // droi.y = 0; // droi.x *= fs_resize_x; // droi.width *= fs_resize_x; // droi.y *= fs_resize_y; // droi.height *= fs_resize_y; // cv::rectangle(m_CheckResult_shareP->resultimg, droi, cv::Scalar(255, 255, 0)); } // 临时存图 if (DetImgInfo_shareP->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_temDraw.png", m_CheckResult_shareP->resultimg); } // 绘制 Roi if (m_pFuntion->function.f_dege_Det.bOpen && m_pFuntion->function.f_dege_Det.bshowRoi) { for (int i = 0; i < m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList->size(); i++) { cv::Rect r = m_pImageAllResult->cameraBaseResult->pEdgeDetResult->pEdgeDet_roiList->at(i); r.x -= m_CutRoi.x; r.y -= m_CutRoi.y; r.x *= fs_resize_x; r.width *= fs_resize_x; r.y *= fs_resize_y; r.height *= fs_resize_y; cv::rectangle(m_CheckResult_shareP->resultimg, r, cv::Scalar(255, 0, 0), 1); if (false) { char buffer[128]; sprintf(buffer, "%d ", i); std::string st1 = buffer; cv::Point p(r.x + r.width * 0.5, r.y + r.height * 0.5); cv::putText(m_CheckResult_shareP->resultimg, st1, p, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 0, 255), 0.5, 1, 0); } } } // cv::imwrite("sss.png", m_CheckResult_shareP->resultimg); return 0; } int ImgCheckAnalysisy::AIClassTypeToConfigType(int nAIQXType, cv::Rect qx_roi) { // CONFIG_QX_NAME_ok_yisi, // 疑似 // CONFIG_QX_NAME_AD_YX, // AD异显(P6873) // CONFIG_QX_NAME_X_line, // X_line(P3351) // CONFIG_QX_NAME_Y_line, // Y_line(P3452) // CONFIG_QX_NAME_Broken_line, // 断线(P3379) // CONFIG_QX_NAME_zara, // ZARA(P1153) // CONFIG_QX_NAME_MTX, // MTX(P1164) // CONFIG_QX_NAME_POL_Cell, // 异物(P1101) // CONFIG_QX_NAME_LD, // 亮点(P1112) // CONFIG_QX_NAME_AD, // 暗点(P1111) // CONFIG_QX_NAME_Scratch_L1, // 一级 轻 划伤(P1557) // CONFIG_QX_NAME_Scratch_L2, // 二级 严重 划伤(P1557) // CONFIG_QX_NAME_Dirty_L0, // 疑似浅层脏污(P0000) // CONFIG_QX_NAME_Dirty_L1, // 轻脏污(P0000) // CONFIG_QX_NAME_Dirty_L2, // 严重脏污(P0000) // CONFIG_QX_NAME_qipao, // 气泡(P0001) // CONFIG_QX_NAME_PS, // ps(P0002) // CONFIG_QX_NAME_Weak_Bright_Mura, // 白GAP(P1654) // CONFIG_QX_NAME_No_Label, // 缺POL(P2833) int resultError_type = CONFIG_QX_NAME_ok_yisi; switch (nAIQXType) { case AI_CLass_QX_NAME_ok_yisi: resultError_type = CONFIG_QX_NAME_ok_yisi; break; case AI_CLass_QX_NAME_yixian: resultError_type = CONFIG_QX_NAME_Class_AD_YX; break; case AI_CLass_QX_NAME_POL_CEL: resultError_type = CONFIG_QX_NAME_POL_Cell; break; case AI_CLass_QX_NAME_zara: resultError_type = CONFIG_QX_NAME_zara; break; case AI_CLass_QX_NAME_ps: resultError_type = CONFIG_QX_NAME_PS; break; case AI_CLass_QX_NAME_line: if (qx_roi.width > qx_roi.height) { resultError_type = CONFIG_QX_NAME_X_line; } else { resultError_type = CONFIG_QX_NAME_Y_line; } break; case AI_CLass_QX_NAME_fangge_line: resultError_type = CONFIG_QX_NAME_Y_line; break; case AI_CLass_QX_NAME_qipao: resultError_type = CONFIG_QX_NAME_qipao; break; case AI_CLass_QX_NAME_qing_huashang: resultError_type = CONFIG_QX_NAME_Scratch_L1; break; case AI_CLass_QX_NAME_mtx: resultError_type = CONFIG_QX_NAME_MTX; break; case AI_CLass_QX_NAME_yisi_qianzangwu: resultError_type = CONFIG_QX_NAME_Dirty_L0; break; case AI_CLass_QX_NAME_qing_zangwu: resultError_type = CONFIG_QX_NAME_Dirty_L1; break; case AI_CLass_QX_NAME_zhong_zangwu: resultError_type = CONFIG_QX_NAME_Dirty_L2; break; case AI_CLass_QX_NAME_andian: resultError_type = CONFIG_QX_NAME_AD; break; case AI_CLass_QX_NAME_huashang: resultError_type = CONFIG_QX_NAME_Scratch_L1; break; case AI_CLass_QX_NAME_zf: resultError_type = CONFIG_QX_NAME_ok_yisi; break; case AI_CLass_QX_NAME_other: resultError_type = CONFIG_QX_NAME_Other; break; default: break; } return resultError_type; return 0; } int ImgCheckAnalysisy::UpdateImgageScale() { if (m_pBasicConfig->fImage_Scale_x > 0 && m_pBasicConfig->fImage_Scale_x < 1 && m_pBasicConfig->fImage_Scale_y > 0 && m_pBasicConfig->fImage_Scale_y < 1) { m_fImgage_Scale_X = m_pBasicConfig->fImage_Scale_x; m_fImgage_Scale_Y = m_pBasicConfig->fImage_Scale_y; } return 0; } int ImgCheckAnalysisy::BLobToDetResult() { long t1 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "BLobToDetResult", " Start old qx num %ld", m_pDetResult->pQx_ErrorList->size()); float fs_x = m_fImgage_Scale_X; float fs_y = m_fImgage_Scale_Y; int qx_num = blobs.blobCount; // 遍历每个检测blob for (int i = 0; i < blobs.blobCount; i++) { cv::Rect roi; roi.x = blobs.blobTab[i].minx; roi.y = blobs.blobTab[i].miny; roi.width = blobs.blobTab[i].maxx - blobs.blobTab[i].minx; roi.height = blobs.blobTab[i].maxy - blobs.blobTab[i].miny; int config_qx_type = blobs.blobTab[i].ErrType; float JudgArea = blobs.blobTab[i].JudgArea; float fsecondArea = JudgArea; std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type]; float flen = blobs.blobTab[i].len; // 长度 QX_ERROR_INFO_ temerror; std::shared_ptr pQxlog = temerror.detlog; pQxlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "BLobToDetResult", " %d /%d roi[%d %d %d %d] qx_name %s qx_type %d JudgArea %0.2f flen %0.2f", i, qx_num, roi.x, roi.y, roi.width, roi.height, qx_name.c_str(), config_qx_type, JudgArea, flen); // 异物和暗点进行二次分割 精确计算面积和长度的精确计算 if (config_qx_type == CONFIG_QX_NAME_AD || config_qx_type == CONFIG_QX_NAME_POL_Cell) { AI_SecondDet::DetConfigResult detconfigresult; detconfigresult.pfunction_secondDet = &m_pFuntion->function.f_SecondDetect; detconfigresult.SetAreaAndLen(blobs.blobTab[i].area, flen); detconfigresult.qx_roi = roi; detconfigresult.qx_name = qx_name; detconfigresult.qx_type = config_qx_type; detconfigresult.strChannel = m_CheckResult_shareP->in_shareImage->strChannel; detconfigresult.fImgage_Scale_X = m_fImgage_Scale_X; detconfigresult.fImgage_Scale_Y = m_fImgage_Scale_Y; detconfigresult.pdetlog = m_pdetlog; int detre = ReCalQX_AreaAndLen(&detconfigresult); pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " ReCalQX_AreaAndLen", "re = %d, Old area %f (mm2) New Area %f; old len %0.2f new %0.2f", detre, JudgArea, detconfigresult.new_Area * fs_x * fs_y, detconfigresult.old_len, detconfigresult.new_len); if (detre == 0) { if (config_qx_type == CONFIG_QX_NAME_POL_Cell) { if (detconfigresult.pfunction_secondDet->pol_open_SingleCheck) { fsecondArea = detconfigresult.new_Area * fs_x * fs_y; } else { blobs.blobTab[i].area = detconfigresult.new_Area; JudgArea = blobs.blobTab[i].area * fs_x * fs_y; blobs.blobTab[i].JudgArea = JudgArea; fsecondArea = JudgArea; } } else { blobs.blobTab[i].area = detconfigresult.new_Area; JudgArea = blobs.blobTab[i].area * fs_x * fs_y; blobs.blobTab[i].JudgArea = JudgArea; fsecondArea = JudgArea; } flen = detconfigresult.new_len; blobs.blobTab[i].len = flen; } } if (config_qx_type == CONFIG_QX_NAME_MTX || config_qx_type == CONFIG_QX_NAME_POL_Cell || config_qx_type == CONFIG_QX_NAME_Other || config_qx_type == CONFIG_QX_NAME_LD) { qx_name = CONFIG_QX_NAME_Names[config_qx_type]; // m_TemCheck.AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD", "stsrt config_qx_type %s ", qx_name.c_str()); int dbresult = LDJudge(config_qx_type, roi, JudgArea, blobs.blobTab[i].maxValue, blobs.blobTab[i].grayDis, pQxlog); //int detre = 1; // 表示L0 和 DP 都有的 亮的 if (dbresult == 1) { config_qx_type = CONFIG_QX_NAME_LD; qx_name = CONFIG_QX_NAME_Names[config_qx_type]; } pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " LD Judge ", "%s qx %s ", Re_TO_STR_Pass_1(dbresult), qx_name.c_str()); } // 如果是chess 画面,缺陷类型直接是chess异常。 if (m_pFuntion->function.f_AIQX.bAllToChess) { config_qx_type = CONFIG_QX_NAME_Chess; qx_name = CONFIG_QX_NAME_Names[config_qx_type]; pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "AllToChess", " Chess, qx %d = %s ", config_qx_type, qx_name.c_str()); } if (m_pFuntion->function.f_AIQX.bPOLToWhitePOL && config_qx_type == CONFIG_QX_NAME_POL_Cell) { bool bchange = true; if (m_pFuntion->function.f_AIQX.b127WhitePOl_UseDP) { cv::Mat DPMaskImg = m_pImageAllResult->cameraBaseResult->DP_MaskImg; if (!DPMaskImg.empty()) { float fiou = CalImgScorl_t(m_pImageAllResult->qx_DetAIResult->AI_MaskImg(roi).clone(), DPMaskImg(roi).clone()); // IOU if (fiou > m_pFuntion->function.f_AIQX.f127WhitePOl_DP_IOU) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "pol change 127Cell", " fiou %f > %f ", fiou, m_pFuntion->function.f_AIQX.f127WhitePOl_DP_IOU); bchange = false; // break; } else { bchange = true; pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "pol change 127Cell", " fiou %f <= %f ", fiou, m_pFuntion->function.f_AIQX.f127WhitePOl_DP_IOU); } } else { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "pol change 127Cell", " DPMaskImg is empty() "); } // m_TemCheck.AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "UseDPMask", " fiou %f < 0.1 ", fiou); } else { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "pol change 127Cell", " NO Use DP "); } if (bchange) { config_qx_type = CONFIG_QX_NAME_127Cell; qx_name = CONFIG_QX_NAME_Names[config_qx_type]; pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "pol change 127Cell", " Suc, qx %d = %s ", config_qx_type, qx_name.c_str()); } else { pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "pol change 127Cell", " Fail"); } // m_TemCheck.AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "DET", " 127 CONFIG_QX_NAME_POL_Cell change CONFIG_QX_NAME_127Cell "); } float fupS = UseUpMaskAnalysis(roi, m_pImageAllResult->qx_DetAIResult->AI_MaskImg, pQxlog); QX_Stauts qx_status = QX_Stauts_Analysis; // 和UP画面进行IOU判断 if (m_pFuntion->function.f_UseUpQX.bOpen) { if (fupS >= m_pFuntion->function.f_UseUpQX.fIOU) { qx_status = QX_Stauts_Draw; pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Up Mask judge", "UseUpQX.bOpen = true ;fupS = %0.2f >= %02f; qx_status = QX_Stauts_Draw", fupS, m_pFuntion->function.f_UseUpQX.fIOU); } else { pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Up Mask judge", "UseUpQX.bOpen = true ;fupS = %0.2f < %02f ", fupS, m_pFuntion->function.f_UseUpQX.fIOU); } } else { pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Up Mask judge", "UseUpQX.bOpen = false ;fupS = %0.2f ", fupS); } // 检测缺陷类型进行判断 bool ban = JudgeQXAnalysis(config_qx_type, pQxlog); if (!ban) { qx_name = CONFIG_QX_NAME_Names[config_qx_type]; pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Judge QX", "qx function close, config_qx_type %s Not Det", qx_name.c_str()); qx_status = QX_Stauts_Draw; } else { pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Judge QX", "qx function open, config_qx_type %s Det", qx_name.c_str()); } // markline 判断,如果某些缺陷在markline内,就屏蔽掉,只绘制。 bool isMarksheildQX = false; isMarksheildQX = Judge_MarkLine_QX(config_qx_type, roi, pQxlog); if (isMarksheildQX) { qx_name = CONFIG_QX_NAME_Names[config_qx_type]; pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "MarkLine_QX", "MarkLine_QX close, config_qx_type %s Not Det", qx_name.c_str()); qx_status = QX_Stauts_Draw; } else { pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "MarkLine_QX", " config_qx_type %s Det", qx_name.c_str()); } pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "add qx", "config_qx_type %d = %s qx_status %d ", config_qx_type, qx_name.c_str(), qx_status); if (true) { temerror.roi = roi; temerror.Idx = m_pDetResult->pQx_ErrorList->size(); temerror.area = blobs.blobTab[i].area; temerror.JudgArea = JudgArea; temerror.JudgArea_second = fsecondArea; temerror.energy = blobs.blobTab[i].energy; temerror.flen = blobs.blobTab[i].len; temerror.nconfig_qx_type = config_qx_type; temerror.qx_name = qx_name; temerror.maxValue = blobs.blobTab[i].maxValue; temerror.grayDis = blobs.blobTab[i].grayDis; temerror.density = blobs.blobTab[i].density; temerror.fUpIou = fupS; temerror.whiteOrBlack = blobs.blobTab[i].whiteOrblack; temerror.qx_status = qx_status; // 添加弱化检测 { cv::Point pCenter; pCenter.x = roi.x + roi.width * 0.5; pCenter.y = roi.y + roi.height * 0.5; for (int iregion = 1; iregion < m_DetRoiList.roiList_Src.size(); iregion++) { bool bInChannel = false; // 当前区域是否有包含的通道。 if (m_pCommonAnalysisyConfig->regionConfigArr.at(iregion).basicInfo.ChannelArry.size() > 0) { std::string strchannelshow = ""; for (const auto &chanel : m_pCommonAnalysisyConfig->regionConfigArr.at(iregion).basicInfo.ChannelArry) { strchannelshow += chanel; strchannelshow += ";"; if (CheckUtil::compareIgnoreCase(m_strCurDetChannel, chanel)) { bInChannel = true; } } pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "pre Judge", "iregion %d channel %s ,channellist %s", iregion, BOOL_TO_STR(bInChannel), strchannelshow.c_str()); } // 需要弱化处理 if (bInChannel) { const std::vector &polygon = m_DetRoiList.roiList_Src[iregion]; double result = cv::pointPolygonTest(polygon, pCenter, false); if (result < 0) { continue; } temerror.detRegionidxList.push_back(iregion); } } // 添加基础检测 temerror.detRegionidxList.push_back(0); } m_pDetResult->pQx_ErrorList->push_back(temerror); // m_pdetlog->AddCheckstr(PrintLevel_3, " BLobToDetResult ", "qx %d ErrType %d ", i, blobs.blobTab[i].ErrType); // printf("- %s idx %d a %f v %d h %f l %f\n", DetImgInfo_shareP->strChannel.c_str(), i, JudgArea, blobs.blobTab[i].maxValue, blobs.blobTab[i].grayDis, flen); } } long t2 = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "BLobToDetResult", " end qx num %ld use time %ld", m_pDetResult->pQx_ErrorList->size(), t2 - t1); return 0; } int ImgCheckAnalysisy::ReCalQX_AreaAndLen(AI_SecondDet::DetConfigResult *pdetConfig) { int paramIdx = m_QxInParamListIdx[pdetConfig->qx_type]; if (paramIdx < 0) { return 0; /* code */ } CheckConfig_Regions_Param *pParam = &m_pRegionAnalysisyParam->checkConfig_Regions_type[ANALYSIS_TYPE_TF].checkConfig_Regions_Param.at(paramIdx); float min_detArea = 99999; bool bhave = false; for (int j = 0; j < pParam->useNum; j++) { if (!pParam->paramArr[j].bEnable) { continue; } bhave = true; float At = pParam->paramArr[j].area; if (At < min_detArea) { min_detArea = At; } } if (!bhave) { min_detArea = 0; } pdetConfig->min_DetArea = min_detArea; // printf("******************** mask %d %d \n", m_pImageAllResult->qx_DetAIResult->AI_MaskImg.cols, m_pImageAllResult->qx_DetAIResult->AI_MaskImg.rows); int re = m_SecondDet.Detect(m_pImageAllResult->detImg, m_pImageAllResult->qx_DetAIResult->AI_MaskImg, pdetConfig); return re; } int ImgCheckAnalysisy::CreatAIDetSmallRoi(const cv::Mat &detimg, std::shared_ptr pAI_Model, std::vector &SmallList) { SmallRoiList.clear(); SmallRoiList.erase(SmallRoiList.begin(), SmallRoiList.end()); cv::Rect cutRoi; cutRoi.x = 0; cutRoi.y = 0; cutRoi.width = detimg.cols - 0; cutRoi.height = detimg.rows - 0; int AIInputImg_width = pAI_Model->input_0.width; int AIInputImg_height = pAI_Model->input_0.height; int re = CheckUtil::cutSmallImg(detimg, SmallRoiList, cutRoi, AIInputImg_width, AIInputImg_height, 0, 0); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Small roi", " cutSmallImg Num %d", SmallRoiList.size()); if (re != 0 || SmallRoiList.size() <= 0) { m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Small roi", " cutSmallImg error %d", re); return 1; } det_SmallImgNum = SmallRoiList.size(); // 字符的增加进去 std::shared_ptr pZF_Result = m_pImageAllResult->cameraBaseResult->pZF_Result; // zf 检测结果 if (pZF_Result && pZF_Result->nresult == 0) { std::vector addroi; // 字符 居中 处理 for (int izf = 0; izf < pZF_Result->ZF_centerPoint.size(); izf++) { bool bedg = false; cv::Point p = pZF_Result->ZF_centerPoint.at(izf); for (int i = 0; i < SmallRoiList.size(); i++) { cv::Rect roi = SmallRoiList.at(i); if (std::abs(p.x - roi.x) < 150 || std::abs(p.x - (roi.x + roi.width)) < 150 || std::abs(p.y - roi.y) < 150 || std::abs(p.y - (roi.y + roi.height)) < 150) { bedg = true; } } if (bedg) { cv::Rect newroi; newroi.x = p.x - AIInputImg_width / 2; newroi.width = AIInputImg_width; if (newroi.x < 0) { newroi.x = 0; } if ((newroi.x + AIInputImg_width) > detimg.cols) { newroi.x = detimg.cols - AIInputImg_width; } newroi.y = p.y - AIInputImg_height / 2; newroi.height = AIInputImg_height; if (newroi.y < 0) { newroi.y = 0; } if ((newroi.y + AIInputImg_height) > detimg.rows) { newroi.y = detimg.rows - AIInputImg_height; } addroi.push_back(newroi); } } // printf("***zf num size=%zu, add New AI roi %zu\n", m_ZF_centerPoint.size(), addroi.size()); m_pdetlog->AddCheckstr(PrintLevel_1, "Small roi", "zf num size=%zu, add New AI roi %zu", pZF_Result->ZF_centerPoint.size(), addroi.size()); for (int izf = 0; izf < addroi.size(); izf++) { SmallRoiList.push_back(addroi.at(izf)); // cv::rectangle(imshow, addroi.at(izf), cv::Scalar(0, 255, 255)); } m_pdetlog->AddCheckstr(PrintLevel_1, "Small roi", " Add New zf AI roi %d", addroi.size()); // cv::imwrite("edg.png", imshow); // printf("---------- at edg 1111111\n"); // getchar(); // 判断 字符 是否在切图的中心 } return 0; } int ImgCheckAnalysisy::AI_Classify_New(const cv::Mat &src_Img, cv::Rect qx_roi, float fjustarea, float *fmaxScore) { std::shared_ptr pAIDet; pAIDet = AI_Factory->AI_defect_Cls_L0; int deal_image_width = pAIDet->input_0.width; int deal_image_height = pAIDet->input_0.height; int re_ConfigType = CONFIG_QX_NAME_ok_yisi; std::vector SmallRoiList; int re = m_AIClassify.GetDetRoiList(src_Img, qx_roi, SmallRoiList, deal_image_width, deal_image_height); int blobNum = SmallRoiList.size(); if (re != 0) { m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Classify", "SmallRoiList Error"); return re_ConfigType; } if (blobNum <= 0) { m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Classify", "SmallRoiList is empyt"); return re_ConfigType; } cv::Size sz = cv::Size(deal_image_width, deal_image_height); int maxcls = 20; int ClsList[20] = {0}; int AI_result = -1; int halfnum = std::ceil(blobNum * 1.0f / 2); AI_Classify_Info ClassifyList[20]; for (int i = 0; i < maxcls; i++) { ClassifyList[i].Init(); } long t2 = CheckUtil::getcurTime(); const int totalTasks = blobNum; int submitted = 0; int completed = 0; int detblobIdx = 0; cv::Mat AI_detImage = m_pImageAllResult->AI_detImg; long t211 = CheckUtil::getcurTime(); while (completed < totalTasks) { // 如果任务还没提交完,且当前处理任务数 < 2,提交新任务 if (submitted < totalTasks && runner->GetProcessingCount() < 10) { std::shared_ptr task = std::make_shared(); task->id = completed; task->roi = SmallRoiList.at(submitted); if (3 != AI_detImage.channels()) { cv::cvtColor(AI_detImage(task->roi), task->input, cv::COLOR_GRAY2BGR); } else { task->input = AI_detImage(task->roi).clone(); } task->engine = pAIDet; task->bclass = true; runner->SubmitTask(task); submitted++; } // 尝试取结果 std::shared_ptr result; if (runner->PopResult(result)) { int cls_num = result->cls_label; if (cls_num >= 0 && cls_num < maxcls) { ClassifyList[cls_num].num++; ClassifyList[cls_num].score += result->cls_score; ClassifyList[cls_num].avgScore = ClassifyList[cls_num].score / ClassifyList[cls_num].num; } completed++; } else { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } int max_num = 0; float max_avgScore = 0; for (int idx = 0; idx < maxcls; idx++) { // ClassifyList[idx].print(std::to_string(idx)); // 数量优先 if (ClassifyList[idx].num > max_num) { max_num = ClassifyList[idx].num; max_avgScore = ClassifyList[idx].avgScore; AI_result = idx; } else if (ClassifyList[idx].num == max_num) { // 得分优先 if (ClassifyList[idx].avgScore > max_avgScore) { max_num = ClassifyList[idx].num; max_avgScore = ClassifyList[idx].avgScore; AI_result = idx; } } } // printf("*********** Model Out %d max_num %d halfnum %d\n", AI_result, max_num, halfnum); int cls_num = AI_result; *fmaxScore = max_avgScore; std::string strclassName = ""; // 启用黑白分类 { int temClass = cls_num; { switch (temClass) { case 0: cls_num = AI_CLass_QX_NAME_ok_yisi; strclassName = "ok_ys"; break; case 1: cls_num = AI_CLass_QX_NAME_POL_CEL; strclassName = "POL_CEL"; break; case 2: cls_num = AI_CLass_QX_NAME_zara; strclassName = "zara"; break; case 3: cls_num = AI_CLass_QX_NAME_andian; strclassName = "andian"; break; case 4: cls_num = AI_CLass_QX_NAME_yisi_qianzangwu; strclassName = "yisi_qianzangwu"; break; case 5: cls_num = AI_CLass_QX_NAME_huashang; strclassName = "huashang"; break; case 6: cls_num = AI_CLass_QX_NAME_line; strclassName = "line"; break; case 7: cls_num = AI_CLass_QX_NAME_ps; strclassName = "ps"; break; case 8: cls_num = AI_CLass_QX_NAME_mtx; strclassName = "mtx"; break; case 9: cls_num = AI_CLass_QX_NAME_yixian; strclassName = "yixian"; break; case 10: cls_num = AI_CLass_QX_NAME_zhong_zangwu; strclassName = "zhong_zangwu"; break; case 11: cls_num = AI_CLass_QX_NAME_qipao; strclassName = "qipao"; break; case 12: cls_num = AI_CLass_QX_NAME_qing_zangwu; strclassName = "qing_zangwu"; break; case 13: cls_num = AI_CLass_QX_NAME_other; strclassName = "other"; break; default: break; } } } m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Classify", "AI Model Out %d = AI Class num %d = %s %f", AI_result, cls_num, strclassName.c_str(), *fmaxScore); // 已经分成 线的 进行二次判断 if (AI_CLass_QX_NAME_line == cls_num) { cls_num = AI_CLass_QX_NAME_line; // printf("\n\n\n\n\n\n\n\n\n--------- flenr %f len %d,widt %d,fjustarea %f\n", flenr, len, widt, fjustarea); } else { // 对不是线的 进行也进行二次判断 // 线的补充分类 if (true) { // 长宽比 float flenr = 1; int len = 0; int widt = 0; if (qx_roi.width > qx_roi.height) { flenr = qx_roi.width * 1.0 / qx_roi.height; len = qx_roi.width; widt = qx_roi.height; } else { flenr = qx_roi.height * 1.0 / qx_roi.width; widt = qx_roi.width; len = qx_roi.height; } // 长宽比过大,判断成 if (flenr > 18 && len > 70 && widt < 220 && fjustarea < 800) { // printf("\n\n\n\n\n\n\n\n\n--------- flenr %f len %d,widt %d,fjustarea %f\n", flenr,len,widt,fjustarea); // getchar(); cls_num = AI_CLass_QX_NAME_line; strclassName = "line"; } // 长宽比过小,判断成 else if (flenr > 4 && len > 180 && widt < 220 && fjustarea < 800 && fjustarea > 20) { // printf("\n\n\n\n\n\n\n\n\n--------- flenr %f len %d,widt %d,fjustarea %f\n", flenr,len,widt,fjustarea); // getchar(); cls_num = AI_CLass_QX_NAME_line; strclassName = "line"; } } } // printf("--------- 0 cls_num %d \n", cls_num); re_ConfigType = AIClassTypeToConfigType(cls_num, qx_roi); m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Classify", "AI Class %d = %s --> Config Class %d , score %f ", cls_num, strclassName.c_str(), re_ConfigType, *fmaxScore); // getchar(); return re_ConfigType; } float ImgCheckAnalysisy::UseUpMaskAnalysis(cv::Rect teroi, const cv::Mat AIMaskImg, std::shared_ptr pQxlog) { float fs = 0; if (!m_pFuntion->function.f_UseUpQX.bOpen) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Up Mask ", "bUseUpImg close "); // printf(">>>>>>>>>>>>>bUseUpImg close \n"); return fs; } if (AIMaskImg.empty()) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Up Mask ", "AIMaskImg.empty() "); return fs; } cv::Mat upMaskImg = m_pImageAllResult->cameraBaseResult->UP_MaskImg; if (upMaskImg.empty()) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Up Mask ", "upMaskImg.empty() "); return fs; } if (teroi.width > 500 || teroi.height > 500) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Up Mask ", "teroi.width > 500 || teroi.height > 500"); return fs; } CheckUtil::SizeRect(teroi, AIMaskImg.cols, AIMaskImg.rows, 20, 20); fs = CalImgScorl(AIMaskImg(teroi).clone(), upMaskImg(teroi).clone()); // m_TemCheck.AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Up Mask ", "x w h d %d %d %d %d fs = %f", teroi.x, teroi.y, teroi.width, teroi.height, fs); // getchar(); return fs; } bool ImgCheckAnalysisy::Judge_MarkLine_QX(int nqx_configType, cv::Rect detqx_Roi, std::shared_ptr pQxlog) { if (!m_pbaseCheckFunction->markLine.bOpen || !m_pbaseCheckFunction->markLine.bUse_qx_Sheild) { pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "MarkLine_QX ", "markline qx sheild is close "); return false; } bool re = false; std::string qx_name = CONFIG_QX_NAME_Names[nqx_configType]; std::string det_qx = ConfigTypeToWebDetType(nqx_configType); for (int i = 0; i < m_pbaseCheckFunction->markLine.sheil_qx_List.size(); i++) { std::string strqx = m_pbaseCheckFunction->markLine.sheil_qx_List.at(i); if (det_qx == strqx) { re = true; break; } } if (!re) { return re; } if (m_pImageAllResult->cameraBaseResult->pMarkLineResult->markLine_Roi_X.width > 0 && m_pImageAllResult->cameraBaseResult->pMarkLineResult->markLine_Roi_X.height > 0) { float ioux = CheckUtil::CalRoi2RoiPre(detqx_Roi, m_pImageAllResult->cameraBaseResult->pMarkLineResult->markLine_Roi_X); pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Judge_MarkLine_QX ", "det qx %s -> markline qx %s x iou %f : %f ", qx_name.c_str(), det_qx.c_str(), ioux, m_pbaseCheckFunction->markLine.qx_sheild_iou); if (ioux > m_pbaseCheckFunction->markLine.qx_sheild_iou) { return true; } } if (m_pImageAllResult->cameraBaseResult->pMarkLineResult->markLine_Roi_Y.width > 0 && m_pImageAllResult->cameraBaseResult->pMarkLineResult->markLine_Roi_Y.height > 0) { float iouy = CheckUtil::CalRoi2RoiPre(detqx_Roi, m_pImageAllResult->cameraBaseResult->pMarkLineResult->markLine_Roi_Y); pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Judge_MarkLine_QX ", "det qx %s -> markline qx %s y iou %f : %f ", qx_name.c_str(), det_qx.c_str(), iouy, m_pbaseCheckFunction->markLine.qx_sheild_iou); if (iouy > m_pbaseCheckFunction->markLine.qx_sheild_iou) { return true; } } return false; } int ImgCheckAnalysisy::CalProductSize() { float fw = m_CutRoi.width * m_fImgage_Scale_X; float fh = m_CutRoi.height * m_fImgage_Scale_Y; fw = std::ceil(fw * 10) / 10; fh = std::ceil(fh * 10) / 10; m_CheckResult_shareP->productWidht_mm = fw; m_CheckResult_shareP->productHeight_mm = fh; m_pdetlog->AddCheckstr(PrintLevel_1, "CalProductSize", "Det ROI [w %d,h %d] (piexl) -> [w %f h %f](mm),scale %f %f", m_CutRoi.width, m_CutRoi.height, fw, fh, m_fImgage_Scale_X, m_fImgage_Scale_Y); return 0; } int ImgCheckAnalysisy::ImgPreDet() { m_pdetlog->AddCheckstr(PrintLevel_0, "ImgPreDet", "=======start"); // 计算产品尺寸 CalProductSize(); if (m_pbaseCheckFunction->saveImg.bSaveClsImg) { creatsavedir(); } m_CheckResult_shareP->cutSrcimg = m_pImageAllResult->detImg; ResizeImg(); m_pImageAllResult->fscale_detToresult_x = m_pImageAllResult->resultImg.cols * 1.0f / m_pImageAllResult->detImg.cols; m_pImageAllResult->fscale_detToresult_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows; return 0; } int ImgCheckAnalysisy::DetPreImage() { m_pdetlog->AddCheckstr(PrintLevel_0, "DetPreImage", "=======start"); // 生成 检测的图片 cv::Mat image; image = m_CheckResult_shareP->in_shareImage->img; if (image.channels() == 3) { cv::cvtColor(image(m_CutRoi), m_pImageAllResult->detImg, cv::COLOR_RGB2GRAY); } else { m_pImageAllResult->detImg = image(m_CutRoi).clone(); } // 对边缘填充 180 { if (!m_pImageAllResult->cameraBaseResult->pEdgeDetResult->edge_cutMask.empty()) { cv::Mat shieldmask = m_pImageAllResult->cameraBaseResult->pEdgeDetResult->edge_cutMask; if (shieldmask.size() == m_pImageAllResult->detImg.size()) { m_pImageAllResult->detImg.setTo(180, shieldmask); // 在 mask 区域设置值为 180 // cv::imwrite(m_CheckResult_shareP->in_shareImage->strChannel + "sss.png", m_TemCheck.temImgList[TEM_IMG_IDX_SrcCrop]); // getchar(); } } } Align_Result *pAlignResult = &m_pImageAllResult->cameraBaseResult->pEdgeDetResult->m_align_Result; m_pdetlog->AddCheckstr(PrintLevel_1, "DetPreImage", "Align_Result Align : det :%d or use :%d", pAlignResult->bDet, pAlignResult->bUse); // 更新 参数图片的crop。 if (pAlignResult->bDet && pAlignResult->bUse) { m_pdetlog->AddCheckstr(PrintLevel_1, "DetPreImage", " =========== Use Align"); m_Crop_Roi_paramImg = pAlignResult->Crop_Roi_ParmImg; if (m_Crop_Roi_paramImg.x < 0) { m_Crop_Roi_paramImg.x = 0; } if (m_Crop_Roi_paramImg.x + m_Crop_Roi_paramImg.width > image.cols) { m_Crop_Roi_paramImg.x = image.cols - m_Crop_Roi_paramImg.width; } if (m_Crop_Roi_paramImg.y < 0) { m_Crop_Roi_paramImg.y = 0; } if (m_Crop_Roi_paramImg.y + m_Crop_Roi_paramImg.height > image.rows) { m_Crop_Roi_paramImg.y = image.rows - m_Crop_Roi_paramImg.height; } m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg; } else { m_pdetlog->AddCheckstr(PrintLevel_1, "DetPreImage", " ===========NO Use Align"); } int re = UpdateSheildMask(m_CheckResult_shareP->in_shareImage->strChannel, m_Crop_Roi_paramImg); // AI 检测的最小尺寸 { std::shared_ptr pAI_Model; pAI_Model = AI_Factory->AI_defect_NF; m_pImageAllResult->AI_Det_Img_Width = pAI_Model->input_0.width; m_pImageAllResult->AI_Det_Img_Height = pAI_Model->input_0.height; // 有一边 不小于模型输入尺寸 // 1、如果输入图不够 模型 输入的最小尺寸,需要调整。 if (m_pImageAllResult->detImg.cols < m_pImageAllResult->AI_Det_Img_Width || m_pImageAllResult->detImg.rows < m_pImageAllResult->AI_Det_Img_Height) { cv::Rect tem_ROI = cv::Rect(0, 0, m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows); int imgw = m_pImageAllResult->detImg.cols; int imgh = m_pImageAllResult->detImg.rows; if (m_pImageAllResult->detImg.cols < m_pImageAllResult->AI_Det_Img_Width) { imgw = m_pImageAllResult->AI_Det_Img_Width; } if (m_pImageAllResult->detImg.rows < m_pImageAllResult->AI_Det_Img_Height) { imgh = m_pImageAllResult->AI_Det_Img_Height; } m_pImageAllResult->AI_detImg = cv::Mat(imgh, imgw, CV_8U, cv::Scalar(180)); m_pImageAllResult->detImg.copyTo(m_pImageAllResult->AI_detImg(tem_ROI)); m_pImageAllResult->AI_shieldImg = cv::Mat(imgh, imgw, CV_8U, cv::Scalar(180)); m_pImageAllResult->shieldImg.copyTo(m_pImageAllResult->AI_shieldImg(tem_ROI)); // shieldImg.copyTo(temImg(tem_ROI)); // shieldImg = temImg.clone(); m_pImageAllResult->bChangeSize = true; m_pdetlog->AddCheckstr(PrintLevel_1, "DetPreImage", "AI_Detect Imge size[%d %d] < AI model size[%d %d] change size true", m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows, m_pImageAllResult->AI_Det_Img_Width, m_pImageAllResult->AI_Det_Img_Height); // 是否要存图 if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_AI_shield.png", m_pImageAllResult->AI_shieldImg); cv::imwrite(m_strCurDetCamChannel + "_AI_detimg.png", m_pImageAllResult->AI_detImg); } } else { m_pImageAllResult->AI_detImg = m_pImageAllResult->detImg; m_pImageAllResult->AI_shieldImg = m_pImageAllResult->shieldImg; } } return 0; } int ImgCheckAnalysisy::UpdateSheildMask(std::string strChannel, cv::Rect roi) { cv::Mat L255shieldMask = m_pImageAllResult->cameraBaseResult->pEdgeDetResult->shieldMask; if (L255shieldMask.empty()) { m_pImageAllResult->shieldImg = cv::Mat(roi.height, roi.width, CV_8UC1, cv::Scalar(0)); } else { m_pImageAllResult->shieldImg = L255shieldMask.clone(); } cv::Mat curdstshieldMask = m_pImageAllResult->shieldImg; if (m_pFuntion != NULL && m_pFuntion->function.f_ShieldRegion.bOpen) { // 这个是界面绘制的 屏蔽区域图片 cv::Mat temmask = m_pFuntion->function.f_ShieldRegion.shieldMask; if (!temmask.empty()) { // 是否要存图 if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_parma_shieldImg.png", temmask); } if (CheckUtil::RoiInImg(roi, temmask)) { if (curdstshieldMask.cols == roi.width && curdstshieldMask.rows == roi.height) { curdstshieldMask.setTo(255, temmask(roi)); // cv::imwrite(strChannel+"1.png",DetImgInfo_shareP->other_channel_Result_mask); // cv::imwrite(strChannel+"2.png",temmask(roi)); m_pdetlog->AddCheckstr(PrintLevel_1, "UpdateSheildMask", "strChannel %s Succ", strChannel.c_str()); } } else { m_pdetlog->AddCheckstr(PrintLevel_1, "UpdateSheildMask", " strChannel %s roi %d %d %d %d != img %d %d error", strChannel.c_str(), roi.x, roi.y, roi.width, roi.height, temmask.cols, temmask.rows); } } else { m_pdetlog->AddCheckstr(PrintLevel_1, "UpdateSheildMask", "strChannel %s m_SheildMask empty error ", strChannel.c_str()); } } else { if(!m_pFuntion->function.f_ShieldRegion.bOpen) m_pdetlog->AddCheckstr(PrintLevel_1, "UpdateSheildMask", "strChannel %s m_pFuntion bOpen is false ", strChannel.c_str()); if(m_pFuntion == NULL) m_pdetlog->AddCheckstr(PrintLevel_1, "UpdateSheildMask", "strChannel %s m_pFuntion is NULL error ", strChannel.c_str()); } // 是否要存图 if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_shield_Result.png", m_pImageAllResult->shieldImg); } // getchar(); return 0; } int ImgCheckAnalysisy::AI_Det_YX(const cv::Mat &cropImg) { m_pdetlog->AddCheckstr(PrintLevel_1, "AI_Det_YX", "============ Start"); std::shared_ptr pAI_Model = AI_Factory->AI_defect_YX_1; if (m_pFuntion && m_pFuntion->function.f_YXDet.bOpen) { if (m_pFuntion->function.f_YXDet.strModle == "YX_1") { pAI_Model = AI_Factory->AI_defect_YX_1; } else { pAI_Model = AI_Factory->AI_defect_YX_2; } } else { m_pdetlog->AddCheckstr(PrintLevel_2, "AI_Det_YX", "============ function close"); return 1; } cv::Mat inImg; cv::Size sz; sz.width = pAI_Model->input_0.width; sz.height = pAI_Model->input_0.height; cv::resize(cropImg, inImg, sz, 0, 0, cv::INTER_AREA); pAI_Model->AIDet(inImg, m_pImageAllResult->YX_MaskImg); if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_YX_in.png", inImg); cv::imwrite(m_strCurDetCamChannel + "_YX_in_mask.png", m_pImageAllResult->YX_MaskImg); } m_pdetlog->AddCheckstr(PrintLevel_1, "AI_Det_YX", "============ end"); return 0; } int ImgCheckAnalysisy::Detect_LackPol(const cv::Mat &cropImg) { m_pdetlog->AddCheckstr(PrintLevel_1, "AI_LackPol", "============ Start"); std::shared_ptr pAI_Model = AI_Factory->AI_defect_LackPol; if (m_pFuntion && m_pFuntion->function.f_Dectect_LackPol.bOpen) { } else { m_pdetlog->AddCheckstr(PrintLevel_2, "AI_LackPol", "============ function close"); return 1; } cv::Mat inImg; cv::Size sz; sz.width = pAI_Model->input_0.width; sz.height = pAI_Model->input_0.height; cv::resize(cropImg, inImg, sz, 0, 0, cv::INTER_AREA); pAI_Model->AIDet(inImg, m_pImageAllResult->LcakPol_MaskImg); if (m_pImageAllResult->result->in_shareImage->bDebugsaveImg) { cv::imwrite(m_strCurDetCamChannel + "_LcakPol_in.png", inImg); cv::imwrite(m_strCurDetCamChannel + "_LcakPol_in_mask.png", m_pImageAllResult->LcakPol_MaskImg); } m_pdetlog->AddCheckstr(PrintLevel_1, "AI_LackPol", "============ end"); return 0; } std::string ImgCheckAnalysisy::ConfigTypeToWebDetType(int nconfigType) { // Function_CONFIG_QX_NAME_ok_yisi, // 疑似 // Function_CONFIG_QX_NAME_YX, // AD异显(P6873) // Function_CONFIG_QX_NAME_line, // X_line(P3351) // Function_CONFIG_QX_NAME_zara, // ZARA(P1153) // Function_CONFIG_QX_NAME_MTX, // MTX(P1164) // Function_CONFIG_QX_NAME_POL_Cell, // 异物(P1101) // Function_CONFIG_QX_NAME_LD, // 亮点(P1112) // Function_CONFIG_QX_NAME_AD, // 暗点(P1111) // Function_CONFIG_QX_NAME_Scratch, // 划伤(P1557) // Function_CONFIG_QX_NAME_Dirty, // 脏污(P0000) // Function_CONFIG_QX_NAME_qipao, // 气泡(P0001) // Function_CONFIG_QX_NAME_PS, // ps(P0002) // Function_CONFIG_QX_NAME_Weak_Bright_Mura, // 白GAP(P1654) // Function_CONFIG_QX_NAME_No_Label, // 缺POL(P2833) // Function_CONFIG_QX_NAME_Other, // 缺POL(P2833) // Function_CONFIG_QX_NAME_Chess, // Chess 异常 // Function_CONFIG_QX_NAME_127Cell, // 白cell std::string strqx = ""; switch (nconfigType) { case CONFIG_QX_NAME_ok_yisi: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_ok_yisi]; break; case CONFIG_QX_NAME_AD_YX: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_YX]; break; case CONFIG_QX_NAME_LackPOL: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_YX]; break; case CONFIG_QX_NAME_Class_AD_YX: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_YX]; break; case CONFIG_QX_NAME_X_line: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_line]; break; case CONFIG_QX_NAME_Y_line: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_line]; break; case CONFIG_QX_NAME_Fangge: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_line]; break; case CONFIG_QX_NAME_Broken_line: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_line]; break; case CONFIG_QX_NAME_zara: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_zara]; break; case CONFIG_QX_NAME_MTX: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_MTX]; break; case CONFIG_QX_NAME_POL_Cell: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_POL_Cell]; break; case CONFIG_QX_NAME_LD: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_LD]; break; case CONFIG_QX_NAME_AD: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_AD]; break; case CONFIG_QX_NAME_Scratch_L1: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Scratch]; break; case CONFIG_QX_NAME_Scratch_L2: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Scratch]; break; case CONFIG_QX_NAME_Dirty_L0: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Dirty]; break; case CONFIG_QX_NAME_Dirty_L1: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Dirty]; break; case CONFIG_QX_NAME_Dirty_L2: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Dirty]; break; case CONFIG_QX_NAME_qipao: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_qipao]; break; case CONFIG_QX_NAME_PS: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_PS]; break; case CONFIG_QX_NAME_Weak_Bright_Mura: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Weak_Bright_Mura]; break; case CONFIG_QX_NAME_No_Label: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_No_Label]; break; case CONFIG_QX_NAME_Other: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Other]; break; case CONFIG_QX_NAME_Chess: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Chess]; break; case CONFIG_QX_NAME_127Cell: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_127Cell]; break; case CONFIG_QX_NAME_white_Cell: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Cell]; break; case CONFIG_QX_NAME_black_Cell: strqx = Function_CONFIG_QX_NAME_Names[Function_CONFIG_QX_NAME_Cell]; break; break; default: break; } return strqx; } bool ImgCheckAnalysisy::JudgeQXAnalysis(int nqx_configType, std::shared_ptr pQxlog) { bool re = false; std::string qx_name = CONFIG_QX_NAME_Names[nqx_configType]; std::string det_qx = ConfigTypeToWebDetType(nqx_configType); for (int i = 0; i < m_pFuntion->function.f_BaseDet.DetQXList.size(); i++) { std::string strqx = m_pFuntion->function.f_BaseDet.DetQXList.at(i); if (det_qx == strqx) { re = true; break; } } pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Judge QX ", "det qx %s -> Funtion qx %s open = %s ", qx_name.c_str(), det_qx.c_str(), BOOL_TO_STR(re)); return re; }