#include "ImageResultJudge.h" ImageResultJudge::ImageResultJudge(/* args */) { m_pCommonAnalysisyConfig = NULL; ptr_thread_Draw = NULL; m_bExit = false; // m_pQX_Merge_Analysis = QX_Merge_Analysis::GetInstance(); } ImageResultJudge::~ImageResultJudge() { } int ImageResultJudge::SetAnalysisyConfig(AnalysisyConfigST *pAnalysisyConfig) { m_pAnalysisyConfig = pAnalysisyConfig; m_pChannelFuntion = &m_pAnalysisyConfig->checkFunction; m_pbaseCheckFunction = &m_pAnalysisyConfig->baseFunction; return 0; } cv::Rect ImageResultJudge::GetCutRoi(cv::Rect &roi, const cv::Mat &img) { cv::Rect cutroi; int pc_x = roi.x + roi.width * 0.5; int pc_y = roi.y + roi.height * 0.5; bool bresize = false; if (roi.width < QX_SAMLLIMG_WIDTH && roi.height < QX_SAMLLIMG_HEIGHT) { cutroi.width = QX_SAMLLIMG_WIDTH; cutroi.x = pc_x - QX_SAMLLIMG_WIDTH * 0.5; cutroi.height = QX_SAMLLIMG_HEIGHT; cutroi.y = pc_y - QX_SAMLLIMG_HEIGHT * 0.5; } else { // 宽 高 if (roi.width > roi.height) { cutroi.width = roi.width + 20; cutroi.x = roi.x - 10; float fsx = QX_SAMLLIMG_HEIGHT * 1.0f / QX_SAMLLIMG_WIDTH; 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 = QX_SAMLLIMG_WIDTH * 1.0f / QX_SAMLLIMG_HEIGHT; 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; } } } return cutroi; } int ImageResultJudge::GetAIDetImg(std::shared_ptr pImageResult, cv::Point pcenter, cv::Mat &AI_InImg, cv::Mat &AI_OutImg) { // printf("%d %d \n", pcenter.x, pcenter.y); // int AINum = pImageResult->AI_Qx_MaskList.size(); for (auto &pAIMask : pImageResult->AI_Qx_MaskList) { cv::Rect roi = pAIMask->roi; if (pcenter.x >= roi.x && pcenter.x <= (roi.x + roi.width) && pcenter.y >= roi.y && pcenter.y <= (roi.y + roi.height)) { // printf("%d %d %d %d \n", roi.x, roi.y, roi.width, roi.height); // 点 (x, y) 在矩形区域内 // printf("--------------------------\n"); AI_InImg = pAIMask->AI_inImg; AI_OutImg = pAIMask->AI_mask; } } return 0; } int ImageResultJudge::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 ImageResultJudge::ResultJudge(std::shared_ptr pImageResult) { std::shared_ptr pImageLog = pImageResult->detlog; int regionNum = m_pCommonAnalysisyConfig->regionConfigArr.size(); if (regionNum <= 0) { return 1; } if (pImageResult->bOnlyBlob) { pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Param Judge", "Analysis Close Only Det"); return 0; } pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Param Judge", "img %s ====================start regon num %d", pImageResult->strChannel.c_str(), regionNum); float fs_resize_x = pImageResult->fscale_detToresult_x; float fs_resize_y = pImageResult->fscale_detToresult_x; std::shared_ptr pDetResult = pImageResult->pDetResult; // 检测结果 std::shared_ptr m_CheckResult_shareP = pImageResult->result; // 返回结果 if (pDetResult == nullptr || pDetResult->pQx_ErrorList == nullptr) { pImageLog->AddCheckstr(PrintLevel_1, "ResultJudge", "Error: pQx_ErrorList is null"); return 1; } std::string strChannel = pImageResult->strChannel; ChannelCheckFunction *pFuntion = GetChannelFuntion(strChannel); if (pFuntion != NULL) { pImageLog->AddCheckstr(PrintLevel_1, "ResultJudge", "Succ: %s pFuntion", strChannel.c_str()); } else { pImageLog->AddCheckstr(PrintLevel_1, "ResultJudge", "Error: %s pFuntion is null", strChannel.c_str()); } int qxNum = pDetResult->pQx_ErrorList->size(); int nSumBLobNUm = 0; float fSunBLobArea = 0; bool bmergeAnnalsisy = false; float fproduct_offx_mm = m_pAnalysisyConfig->commonCheckConfig.baseConfig.fProduct_Off_X_mm; int fproduct_offx_piexl = int(fproduct_offx_mm / m_fImgage_Scale_X); pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Param Judge", "fproduct_offx_mm %f %d", fproduct_offx_mm, fproduct_offx_piexl); for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); std::shared_ptr pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog; // pQxLog->bPrintStr = true; cv::Rect roi = QX_info->roi; float JudgArea = QX_info->JudgArea; float JudgArea_second = QX_info->JudgArea_second; float flen = QX_info->flen; float grayDis = QX_info->grayDis; int energy = QX_info->energy; float fupS = QX_info->fUpIou; int maxValue = QX_info->maxValue; float density = QX_info->density; int QX_whiteBLACK = QX_info->whiteOrBlack; int config_qx_type = QX_info->nconfig_qx_type; QX_Stauts qx_status = QX_info->qx_status; std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type]; std::string qx_wb = WHITE_BLCAK_Names[QX_whiteBLACK]; std::string strdetRegionidxList = "num:" + to_string(QX_info->detRegionidxList.size()); int count = QX_info->detRegionidxList.size(); for (int ij = 0; ij < count; ij++) { strdetRegionidxList += " " + to_string(QX_info->detRegionidxList[ij] + 1); } pQxLog->AddCheckstr(PrintLevel_1, "ResultJudge", "qxidx: %d/%d qx_status %d roi[%d %d %d %d] qx %d %s %s JudgArea %f hj %f len %f energy %d region %s", qxidx, qxNum, qx_status, roi.x, roi.y, roi.width, roi.height, config_qx_type, qx_name.c_str(), qx_wb.c_str(), JudgArea, grayDis, flen, energy, strdetRegionidxList.c_str()); cv::Point pCenter; pCenter.x = roi.x + roi.width * 0.5; pCenter.y = roi.y + roi.height * 0.5; bool bNG_Status = false; bool bYS_Status = false; bool Judge_Status = false; QX_info->result = QX_RESULT_TYPE_NoJduge; // 在其他位置已经判断了 不进入分析。直接绘制。 if (qx_status == QX_Stauts_Draw) { pQxLog->AddCheckstr(PrintLevel_2, "QX info", ">>>>>>>> QX_Stauts_Draw"); continue; } // 弱化处理 bool bpreSucc = true; int pre_result = AnalysisResult_Pre(QX_info); if (pre_result > 0) { bpreSucc = false; // 看看是否满足 疑是缺陷。 } else { nSumBLobNUm++; fSunBLobArea += JudgArea; } int nerrortype = 0; int checkFlage = 0; // 基础分析 不是亮点 if (config_qx_type >= 0 && config_qx_type != CONFIG_QX_NAME_LD) { // 遍历当前区域所属的 区域进行参数判断。 for (auto iregion : QX_info->detRegionidxList) { // 只处理基础的检测参数。 if (iregion != 0) { continue; } pQxLog->AddCheckstr(PrintLevel_2, "QX info", ">>>>>>>> region %d ", iregion + 1); // 1、判断当前区域是否要检测该通道画面。 // 2、基础的参数判断 if (iregion >= regionNum) { pQxLog->AddCheckstr(PrintLevel_3, "QX info", "Error regionIdx %d > param size %d ", iregion, regionNum); continue; } if (config_qx_type >= CONFIG_QX_NAME_count || config_qx_type < 0) { pQxLog->AddCheckstr(PrintLevel_3, "QX info", "Error def_type %d size %d ", config_qx_type, CONFIG_QX_NAME_count); continue; } int paramIdx = m_QxInParamListIdx[config_qx_type]; if (paramIdx < 0) { pQxLog->AddCheckstr(PrintLevel_3, "qx error", " paramIdx < 0 "); continue; } for (int ict = 0; ict < ANALYSIS_TYPE_COUNT; ict++) { // 没有通过弱化区验证 if (!bpreSucc) { // 只对疑是检测 if (ict == ANALYSIS_TYPE_TF) { continue; } } std::string str_checkflag = "QX-check"; checkFlage = ict; if (ict == ANALYSIS_TYPE_YS) { str_checkflag = "YS-check"; } pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "QX info", " %s start", str_checkflag.c_str()); CheckConfig_Regions_Param *pParam = &m_pCommonAnalysisyConfig->regionConfigArr.at(iregion).checkConfig_Regions_type[ict].checkConfig_Regions_Param.at(paramIdx); bool bUse = false; for (int j = 0; j < pParam->useNum; j++) { bool result = true; if (!pParam->paramArr[j].bEnable) { continue; } // 对数量和距离有需求。 if (pParam->paramArr[j].num > 0 || pParam->paramArr[j].dis > 0) { pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "param---", "num %d >0 or dis %f > 0 QX_ALL Analysisy", pParam->paramArr[j].num, pParam->paramArr[j].dis); continue; } bUse = true; float At = pParam->paramArr[j].area; float Et = pParam->paramArr[j].energy; float hj = pParam->paramArr[j].hj; float Len = pParam->paramArr[j].length; float md = pParam->paramArr[j].density; Judge_Status = true; float detArea = JudgArea; if (config_qx_type == CONFIG_QX_NAME_POL_Cell && JudgArea_second > 0) { detArea = JudgArea_second; } // 满足其中一个缺陷要求。 if (energy >= Et && detArea >= At && grayDis >= hj && flen >= Len && density >= md) { nerrortype = 1; result = false; if (ict == ANALYSIS_TYPE_YS) { bYS_Status = true; } else { bNG_Status = true; } } if (!result) { pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "result", "%s param idx %d / %d parma A %f E %f HJ %f L %f", BOOL_TO_STROK(result), j + 1, pParam->useNum, At, Et, hj, Len); } else { pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "result", "%s param idx %d / %d", BOOL_TO_STROK(result), j + 1, pParam->useNum); } if (detArea < At) { pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Area", "%s -> %f %s %f ", BOOL_TO_STR(detArea >= At), detArea, BOOL_TO_ThanLess(detArea >= At), At); } if (energy < Et) { pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Energy", "%s -> %d %s %f ", BOOL_TO_STR(energy >= Et), energy, BOOL_TO_ThanLess(energy >= Et), Et); } if (grayDis < hj) { pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "HJ", "%s -> %f %s %f ", BOOL_TO_STR(grayDis >= hj), grayDis, BOOL_TO_ThanLess(grayDis > hj), hj); } if (flen < Len) { pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Len", "%s -> %f %s %f ", BOOL_TO_STR(flen >= Len), flen, BOOL_TO_ThanLess(flen > Len), Len); } if (!result) { break; } } if (!bUse) { pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "info", "Not Use Param Judge"); } if (nerrortype != 0) { pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "info", " %s end result: erorr type %s", str_checkflag.c_str(), qx_name.c_str()); break; } else { pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "info", " %s end result: OK ", str_checkflag.c_str()); } } } } else { // 亮点 if (config_qx_type == CONFIG_QX_NAME_LD) { Judge_Status = true; checkFlage = ANALYSIS_TYPE_TF; nerrortype = 1; } } // 暗点 3S 分析 对 好品 或者 是 疑是的缺陷进行3S分析。S数量分析。 3S的暗点直接NG. // if ((nerrortype == 0 || checkFlage != ANALYSIS_TYPE_TF) && // config_qx_type == CONFIG_QX_NAME_AD && pFuntion && // pFuntion->function.f_AD_Check.bOpen && // pFuntion->function.f_AD_Check.analysis_s.bOpen && // pFuntion->function.f_AD_Check.analysis_s.NG_3s && bpreSucc) if ((nerrortype == 0 || checkFlage != ANALYSIS_TYPE_TF) && config_qx_type == CONFIG_QX_NAME_AD && m_pbaseCheckFunction && m_pbaseCheckFunction->ad_check.bOpen && m_pbaseCheckFunction->ad_check.analysis_s.bOpen && m_pbaseCheckFunction->ad_check.analysis_s.NG_3s && bpreSucc) { Judge_Status = true; int det_s_Vale = 0; if (JudgArea >= pFuntion->function.f_AD_Check.S_standard_3s.area && flen >= pFuntion->function.f_AD_Check.S_standard_3s.len) { nerrortype = 1; checkFlage = ANALYSIS_TYPE_TF; bNG_Status = true; pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "info", " AD 3S result NG, det area %f len %f >=3s param area %f len %f ", JudgArea, flen, pFuntion->function.f_AD_Check.S_standard_3s.area, pFuntion->function.f_AD_Check.S_standard_3s.len); } else { pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "info", " AD 3S result OK, det area %f len %f < 3s param area %f len %f ", JudgArea, flen, pFuntion->function.f_AD_Check.S_standard_3s.area, pFuntion->function.f_AD_Check.S_standard_3s.len); } } std::string resultType = "OK"; if (!Judge_Status) { QX_info->result = QX_RESULT_TYPE_NoJduge; } else { if (bNG_Status) { QX_info->result = QX_RESULT_TYPE_NG; } else if (bYS_Status) { QX_info->result = QX_RESULT_TYPE_YS; } else { QX_info->result = QX_RESULT_TYPE_OK; } } QX_info->result_name = QX_RESULT_TYPE_Names[QX_info->result]; resultType = QX_info->result_name; pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " Param Judge", "qx %s ,result = %s", qx_name.c_str(), resultType.c_str()); // 当前是好品 同时要通过预处理 if (!bNG_Status && bpreSucc) { // 目前为止判断是好品 if (!bNG_Status && pFuntion->function.f_Big_QX.bOpen) { Judge_Status = true; bool berror = false; // 满足大缺陷的判断要求,则 NG if (JudgArea >= pFuntion->function.f_Big_QX.Single_Area && grayDis >= pFuntion->function.f_Big_QX.Single_HJ && flen >= pFuntion->function.f_Big_QX.Single_Len) { berror = true; nerrortype = 1; checkFlage = ANALYSIS_TYPE_TF; bNG_Status = true; } pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Big QX single result ", "%s ", BOOL_TO_STROK(!berror)); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Area", "%s -> %f %s %f ", BOOL_TO_STR(JudgArea >= pFuntion->function.f_Big_QX.Single_Area), JudgArea, BOOL_TO_ThanLess(JudgArea >= pFuntion->function.f_Big_QX.Single_Area), pFuntion->function.f_Big_QX.Single_Area); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "HJ", "%s -> %f %s %d", BOOL_TO_STR(grayDis >= pFuntion->function.f_Big_QX.Single_HJ), grayDis, BOOL_TO_ThanLess(grayDis >= pFuntion->function.f_Big_QX.Single_HJ), pFuntion->function.f_Big_QX.Single_HJ); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Len", "%s -> %f %s %f ", BOOL_TO_STR(flen >= pFuntion->function.f_Big_QX.Single_Len), flen, BOOL_TO_ThanLess(flen >= pFuntion->function.f_Big_QX.Single_Len), pFuntion->function.f_Big_QX.Single_Len); } // 总面积判断 if (!bNG_Status && pFuntion->function.f_Big_QX.bOpen) { if (nSumBLobNUm <= pFuntion->function.f_Big_QX.Sum_blob_Num) { Judge_Status = true; bool berror = false; if (nSumBLobNUm <= pFuntion->function.f_Big_QX.Sum_blob_Num && fSunBLobArea >= pFuntion->function.f_Big_QX.Sum_Area) { berror = true; nerrortype = 1; checkFlage = ANALYSIS_TYPE_TF; bNG_Status = true; } pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Big QX sum result", "%s ", BOOL_TO_STROK(!berror)); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Area", "%s -> %f %s %f ", BOOL_TO_STR(fSunBLobArea >= pFuntion->function.f_Big_QX.Sum_Area), fSunBLobArea, BOOL_TO_ThanLess(fSunBLobArea >= pFuntion->function.f_Big_QX.Sum_Area), pFuntion->function.f_Big_QX.Sum_Area); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "nSumBLobNUm", "cur Num %d <= %d ", nSumBLobNUm, pFuntion->function.f_Big_QX.Sum_blob_Num); } } if (!Judge_Status) { QX_info->result = QX_RESULT_TYPE_NoJduge; } else { if (bNG_Status) { QX_info->result = QX_RESULT_TYPE_NG; } else if (bYS_Status) { QX_info->result = QX_RESULT_TYPE_YS; } else { QX_info->result = QX_RESULT_TYPE_OK; } } QX_info->result_name = QX_RESULT_TYPE_Names[QX_info->result]; resultType = QX_info->result_name; pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " big qx ", "qx %s ,result = %s", qx_name.c_str(), resultType.c_str()); } if (bNG_Status) { m_CheckResult_shareP->nresult = 1; } if (bYS_Status) { m_CheckResult_shareP->nYS_result = 1; } m_CheckResult_shareP->checkStatus = 0; // 生成缺陷小图 if (bYS_Status || bNG_Status) { // 生成图片 QXImageResult tem; tem.idx = qxidx; cv::Rect CutRoi = GetCutRoi(roi, pImageResult->detImg); // CheckUtil::printROI(CutRoi, "CutRoi"); cv::Size sz = cv::Size(QX_SAMLLIMG_WIDTH, QX_SAMLLIMG_HEIGHT); if (pImageResult->detImg.channels() == 1) { cv::cvtColor(pImageResult->detImg(CutRoi), tem.srcImg, cv::COLOR_GRAY2BGR); } else { tem.srcImg = pImageResult->detImg(CutRoi).clone(); } cv::resize(tem.srcImg, tem.resizeImg, sz); int nqx_type = ConfigTypeToResultType(config_qx_type); tem.type = nqx_type; tem.area = JudgArea; tem.energy = energy; tem.hj = grayDis; tem.max_v = maxValue; tem.strTypeName = QX_Result_Names[nqx_type]; tem.qx_Code = QX_Result_Code[nqx_type]; tem.srcImgroi = roi; tem.len = flen; tem.qx_type = 0; tem.fScore = 0; tem.density = 0; tem.resizeImgroi.x = roi.x * fs_resize_x; tem.resizeImgroi.width = roi.width * fs_resize_x; tem.resizeImgroi.y = roi.y * fs_resize_y; tem.resizeImgroi.height = roi.height * fs_resize_y; tem.x_pixel = roi.x + roi.width * 0.5; tem.y_pixel = roi.y + roi.height * 0.5; tem.x_mm = tem.x_pixel * m_fImgage_Scale_X; tem.y_mm = tem.y_pixel * m_fImgage_Scale_Y; tem.CutImgroi = roi; tem.CutImgroi.x -= CutRoi.x; tem.CutImgroi.y -= CutRoi.y; if (bNG_Status) { m_CheckResult_shareP->defectResultList[nqx_type].nresult = 1; m_CheckResult_shareP->defectResultList[nqx_type].keyName = QX_Result_Names[nqx_type]; m_CheckResult_shareP->defectResultList[nqx_type].keyCode = QX_Result_Code[nqx_type]; m_CheckResult_shareP->defectResultList[nqx_type].num++; if (m_CheckResult_shareP->nresult <= ERROR_TYPE_OK) { m_CheckResult_shareP->nresult = nqx_type; } GetAIDetImg(pImageResult, pCenter, tem.AI_in_Img, tem.AI_out_img); m_CheckResult_shareP->qxImageResult.push_back(tem); } else { if (m_CheckResult_shareP->nYS_result <= ERROR_TYPE_OK) { m_CheckResult_shareP->nYS_result = nqx_type; } GetAIDetImg(pImageResult, pCenter, tem.AI_in_Img, tem.AI_out_img); m_CheckResult_shareP->YS_ImageResult.push_back(tem); } } // 对于大面积 的zara和 异显NG ,可以不接着分析后续的数据了。应为后续估计有很多错误类别。 if (bNG_Status && JudgArea > 500) { if (config_qx_type == CONFIG_QX_NAME_AD_YX || config_qx_type == CONFIG_QX_NAME_zara) { pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "stop Judge ", "stop : JudgArea > 500 onfig_qx_type == CONFIG_QX_NAME_AD_YX || config_qx_type == CONFIG_QX_NAME_zara"); break; } } // 加入到 缺陷 分析类中 if (bpreSucc) { { int disnumqxidx = m_pQX_Merge_Analysis->ConfigTypeToQXAnalysis(config_qx_type); if (disnumqxidx >= 0) { QX_Info temqx; temqx.result = 0; if (bNG_Status) { temqx.result = 1; } temqx.roi = roi; temqx.product_roi = roi; temqx.product_roi.x += fproduct_offx_piexl; temqx.camera_name = pImageResult->cameraBaseResult->strCameraName; temqx.channel_name = pImageResult->strChannel; temqx.area = JudgArea; temqx.blobIdx = qxidx; temqx.energy = energy; temqx.hj = grayDis; temqx.length = flen; temqx.density = density; temqx.plocatin_pixel.x = roi.x + roi.width * 0.5; temqx.plocatin_pixel.y = roi.y + roi.height * 0.5; temqx.plocatin_mm.x = temqx.plocatin_pixel.x * m_fImgage_Scale_X; temqx.plocatin_mm.y = temqx.plocatin_pixel.y * m_fImgage_Scale_Y; temqx.pLocation_Product_mm.x = temqx.plocatin_mm.x + fproduct_offx_mm; temqx.pLocation_Product_mm.y = temqx.plocatin_mm.y + 0; bool bad = m_pQX_Merge_Analysis->AddQxInfo(disnumqxidx, temqx, pQxLog, pImageLog); if (bad) { bmergeAnnalsisy = true; } pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " Use Num And Dis Judge ", "qx %s ,Add %s %s", qx_name.c_str(), BOOL_TO_STR_Error(bad), CheckUtil::getCurTimeHMS().c_str()); } } } pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " Cur Result ", "qx %s ,result = %s", qx_name.c_str(), resultType.c_str()); } for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); switch (QX_info->result) { case QX_RESULT_TYPE_OK: pImageResult->Ok_num++; break; case QX_RESULT_TYPE_NG: pImageResult->NG_num++; break; case QX_RESULT_TYPE_YS: pImageResult->YS_num++; break; case QX_RESULT_TYPE_NoJduge: pImageResult->NoJudge_num++; break; default: pImageResult->NoJudge_num++; break; } } pImageLog->bPrintStr = true; pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Param Judge", "img %s ====================End ng %d ys %d ok %d nojudge %d ", pImageResult->strChannel.c_str(), pImageResult->NG_num, pImageResult->YS_num, pImageResult->Ok_num, pImageResult->NoJudge_num); pImageLog->bPrintStr = false; return 0; } int ImageResultJudge::UpdateMergedet(std::shared_ptr pCheck_Result) { m_pQX_Merge_Analysis = pCheck_Result->productBaseResult->pQX_Merge_Analysis; SetMergeConfig(pCheck_Result->cameraBaseResult->strCameraName); // pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Param Judge", "UpdateMergedet strCameraName %s", pCheck_Result->cameraBaseResult->strCameraName); return 0; } int ImageResultJudge::MergeResult(std::shared_ptr pImageResult, QX_Analysis_Result_List *ptemre) { std::shared_ptr pImageLog = pImageResult->detlog; if (pImageResult->bOnlyBlob) { return 0; } float fs_resize_x = pImageResult->fscale_detToresult_x; float fs_resize_y = pImageResult->fscale_detToresult_x; std::shared_ptr pDetResult = pImageResult->pDetResult; // 检测结果 std::shared_ptr m_CheckResult_shareP = pImageResult->result; // 返回结果 if (pDetResult == nullptr || pDetResult->pQx_ErrorList == nullptr) { return 1; } int qxNum = pDetResult->pQx_ErrorList->size(); for (int iqx = 0; iqx < (int)ptemre->resultList.size(); iqx++) { if (ptemre->resultList.at(iqx).channel_name != pImageResult->strChannel || ptemre->resultList.at(iqx).camera_name != pImageResult->cameraBaseResult->strCameraName) { continue; } pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Param Judge", "img %s === merge idx %d qxblobidx %d ", pImageResult->strChannel.c_str(), iqx, ptemre->resultList.at(iqx).blobIdx); // 遍历每个检测blob for (int i = 0; i < qxNum; i++) { if (i != ptemre->resultList.at(iqx).blobIdx) { continue; } // m_TemCheck.AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "qx", " Add QX %d / %d", iqx, (int)ptemre->resultList.size()); QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(i); std::shared_ptr pQxLog = pDetResult->pQx_ErrorList->at(i).detlog; cv::Rect roi = QX_info->roi; float JudgArea = QX_info->JudgArea; float flen = QX_info->flen; float grayDis = QX_info->grayDis; int energy = QX_info->energy; float fupS = QX_info->fUpIou; int maxValue = QX_info->maxValue; float density = QX_info->density; int config_qx_type = QX_info->nconfig_qx_type; std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type]; cv::Point pCenter; pCenter.x = roi.x + roi.width * 0.5; pCenter.y = roi.y + roi.height * 0.5; // 确认错误类别 QXImageResult tem; tem.idx = i; cv::Rect CutRoi = GetCutRoi(roi, pImageResult->detImg); cv::Size sz = cv::Size(QX_SAMLLIMG_WIDTH, QX_SAMLLIMG_HEIGHT); if (pImageResult->detImg.channels() == 1) { cv::cvtColor(pImageResult->detImg(CutRoi), tem.srcImg, cv::COLOR_GRAY2BGR); } else { tem.srcImg = pImageResult->detImg(CutRoi).clone(); } cv::resize(tem.srcImg, tem.resizeImg, sz); int nerrortype = 1; int checkFlage = ANALYSIS_TYPE_TF; float fmaxScore = 0; pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "qx", "roi[%d %d %d %d] qx %d %s JudgArea %f hj %f len %f energy %d,", roi.x, roi.y, roi.width, roi.height, config_qx_type, qx_name.c_str(), JudgArea, grayDis, flen, energy); // 生成缺陷小图 if (nerrortype != 0) { int nqx_type = ConfigTypeToResultType(config_qx_type); tem.type = nqx_type; tem.area = JudgArea; tem.energy = energy; tem.hj = grayDis; tem.max_v = maxValue; tem.density = density; tem.strTypeName = QX_Result_Names[nqx_type]; tem.qx_Code = QX_Result_Code[nqx_type]; tem.srcImgroi = roi; tem.len = flen; tem.qx_type = ptemre->resultList.at(iqx).error_Type; tem.minDis_mm = ptemre->resultList.at(iqx).mindis; tem.qx_num = ptemre->resultList.at(iqx).qx_Num; tem.resizeImgroi.x = roi.x * fs_resize_x; tem.resizeImgroi.width = roi.width * fs_resize_x; tem.resizeImgroi.y = roi.y * fs_resize_y; tem.resizeImgroi.height = roi.height * fs_resize_y; tem.x_pixel = roi.x + roi.width * 0.5; tem.y_pixel = roi.y + roi.height * 0.5; tem.x_mm = tem.x_pixel * m_fImgage_Scale_X; tem.y_mm = tem.y_pixel * m_fImgage_Scale_Y; tem.CutImgroi = roi; tem.CutImgroi.x -= CutRoi.x; tem.CutImgroi.y -= CutRoi.y; if (checkFlage == ANALYSIS_TYPE_TF) { m_CheckResult_shareP->defectResultList[nqx_type].nresult = 1; m_CheckResult_shareP->defectResultList[nqx_type].keyName = QX_Result_Names[nqx_type]; m_CheckResult_shareP->defectResultList[nqx_type].keyCode = QX_Result_Code[nqx_type]; m_CheckResult_shareP->defectResultList[nqx_type].num++; pDetResult->pQx_ErrorList->at(i).result = 1; if (m_CheckResult_shareP->nresult <= ERROR_TYPE_OK) { m_CheckResult_shareP->nresult = nqx_type; } GetAIDetImg(pImageResult, pCenter, tem.AI_in_Img, tem.AI_out_img); m_CheckResult_shareP->qxImageResult.push_back(tem); } } // addInDrawBlob_New(-9, i, QX_info, fs_resize_x, fs_resize_y); // if (config_qx_type != CONFIG_QX_NAME_AD && config_qx_type != CONFIG_QX_NAME_POL_Cell) { for (auto it_ys = m_CheckResult_shareP->YS_ImageResult.begin(); it_ys != m_CheckResult_shareP->YS_ImageResult.end();) { if (it_ys->idx == i) { it_ys = m_CheckResult_shareP->YS_ImageResult.erase(it_ys); // 删除元素,并更新迭代器 } else { ++it_ys; // 继续检查下一个元素 } } } std::string strresult = "OK"; if (nerrortype != 0) { if (checkFlage == ANALYSIS_TYPE_TF) { strresult = "NG"; QX_info->result = QX_RESULT_TYPE_NG; QX_info->result_name = QX_RESULT_TYPE_Names[QX_RESULT_TYPE_NG]; } else { strresult = "YS"; QX_info->result = QX_RESULT_TYPE_YS; QX_info->result_name = QX_RESULT_TYPE_Names[QX_RESULT_TYPE_YS]; } } pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " Add num or Dis reuslt ", "qx %s ,result = %s", qx_name.c_str(), strresult.c_str()); } } for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); switch (QX_info->result) { case QX_RESULT_TYPE_OK: pImageResult->Ok_num++; break; case QX_RESULT_TYPE_NG: pImageResult->NG_num++; break; case QX_RESULT_TYPE_YS: pImageResult->YS_num++; break; case QX_RESULT_TYPE_NoJduge: pImageResult->NoJudge_num++; break; default: pImageResult->NoJudge_num++; break; } } pImageLog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Add num or Dis reuslt", "img %s ====================End ng %d ys %d ok %d nojudge %d ", pImageResult->strChannel.c_str(), pImageResult->NG_num, pImageResult->YS_num, pImageResult->Ok_num, pImageResult->NoJudge_num); return 0; } int ImageResultJudge::UpdateConfig(std::string strcameraName) { if (m_pAnalysisyConfig->commonCheckConfig.nodeConfigArr.size() > 0) { m_pCommonAnalysisyConfig = &m_pAnalysisyConfig->commonCheckConfig.nodeConfigArr.at(0); m_pRegionAnalysisyParam = &m_pCommonAnalysisyConfig->regionConfigArr.at(0); m_pBasicConfig = &m_pAnalysisyConfig->commonCheckConfig.baseConfig; } else { m_pCommonAnalysisyConfig = NULL; } GetParamidx(); UpdateImgageScale(); SetInDetConfig(strcameraName); return 0; } int ImageResultJudge::DrawResult(std::shared_ptr pImageResult) { std::shared_ptr txtbackgroundk = std::make_shared(); if (!ptr_thread_Draw) { ptr_thread_Draw = std::make_shared(std::bind(&ImageResultJudge::ThreadDraw, this)); } float fs_resize_x = pImageResult->fscale_detToresult_x; float fs_resize_y = pImageResult->fscale_detToresult_x; std::shared_ptr m_CheckResult_shareP = pImageResult->result; // 返回结果 std::vector m_drawList; if (m_CheckResult_shareP->resultimg.empty()) { return 0; } cv::Scalar color_NG = cv::Scalar(0, 0, 255); cv::Scalar color_Ys = cv::Scalar(0, 255, 255); cv::Scalar color_Nojudge = cv::Scalar(0, 255, 0); long t1 = CheckUtil::getcurTime(); for (int i = 0; i < m_CheckResult_shareP->qxImageResult.size(); i++) { std::shared_ptr draw_qx = std::make_shared(); QXImageResult *pqx = &m_CheckResult_shareP->qxImageResult.at(i); cv::Rect drawroi = pqx->resizeImgroi; cv::Point cp = cv::Point(drawroi.x + drawroi.width * .5, drawroi.y + drawroi.height * 0.5); int r = drawroi.width; if (drawroi.height > r) { r = drawroi.height; } r += 10; draw_qx->dr = r; draw_qx->cp = cp; draw_qx->color = color_NG; draw_qx->drawImg = m_CheckResult_shareP->resultimg; draw_qx->type = Draw_circle; sendTask(draw_qx); std::shared_ptr draw_str = std::make_shared(); draw_str->drawImg = m_CheckResult_shareP->resultimg; draw_str->type = Draw_str; draw_str->color = color_NG; draw_str->cp = cp; draw_str->txtP = cv::Point(draw_qx->cp.x + r, draw_qx->cp.y - r); draw_str->txtsize = 0.5; draw_str->txtbackgroundk = txtbackgroundk; cv::Rect srcroi = pqx->srcImgroi; cv::Point srccp = cv::Point(srcroi.x + srcroi.width * .5, srcroi.y + srcroi.height * 0.5); char buffer[128]; { std::string text = std::to_string(pqx->idx) + ":" + pqx->strTypeName; draw_str->strlist.push_back(text); } { sprintf(buffer, " p:%d %d", srccp.x, srccp.y); std::string text = buffer; draw_str->strlist.push_back(text); } { sprintf(buffer, " len %0.2f A: %0.2f hj %0.2f ", pqx->len, pqx->area, pqx->hj); std::string text = buffer; draw_str->strlist.push_back(text); } // { // sprintf(buffer, " E:%0.2f hj %0.2f", pqx->energy, pqx->hj); // std::string text = buffer; // draw_str->strlist.push_back(text); // } sendTask(draw_str); // 在小图上绘制 { cv::Rect drawroi = pqx->CutImgroi; cv::Point cp = cv::Point(drawroi.x + drawroi.width * .5, drawroi.y + drawroi.height * 0.5); int r = drawroi.width; if (drawroi.height > r) { r = drawroi.height; } r += 10; std::shared_ptr draw_qx_small = std::make_shared(); draw_qx_small->drawImg = pqx->srcImg; draw_qx_small->cp = cp; draw_qx_small->dr = r; draw_qx_small->color = color_NG; draw_qx_small->type = Draw_circle; sendTask(draw_qx_small); std::shared_ptr draw_str_small = std::make_shared(); draw_str_small->drawImg = pqx->srcImg; draw_str_small->type = Draw_str; draw_str_small->color = color_NG; draw_str_small->txtP = cp; draw_str_small->cp = cp; draw_str_small->strlist.assign(draw_str->strlist.begin(), draw_str->strlist.end()); draw_str_small->txtsize = 0.45; sendTask(draw_str_small); } } for (int i = 0; i < m_CheckResult_shareP->YS_ImageResult.size(); i++) { std::shared_ptr draw_qx = std::make_shared(); QXImageResult *pqx = &m_CheckResult_shareP->YS_ImageResult.at(i); cv::Rect drawroi = pqx->resizeImgroi; cv::Point cp = cv::Point(drawroi.x + drawroi.width * .5, drawroi.y + drawroi.height * 0.5); int r = drawroi.width; if (drawroi.height > r) { r = drawroi.height; } r += 10; draw_qx->dr = r; draw_qx->cp = cp; draw_qx->color = color_Ys; draw_qx->drawImg = m_CheckResult_shareP->resultimg; draw_qx->type = Draw_circle; sendTask(draw_qx); std::shared_ptr draw_str = std::make_shared(); draw_str->drawImg = m_CheckResult_shareP->resultimg; draw_str->type = Draw_str; draw_str->color = color_Ys; draw_str->cp = cp; draw_str->txtP = cv::Point(draw_qx->cp.x + r, draw_qx->cp.y - r); draw_str->txtbackgroundk = txtbackgroundk; draw_str->txtsize = 0.5; cv::Rect srcroi = pqx->srcImgroi; cv::Point srccp = cv::Point(srcroi.x + srcroi.width * .5, srcroi.y + srcroi.height * 0.5); char buffer[128]; { std::string text = std::to_string(pqx->idx); draw_str->strlist.push_back(text); } // { // sprintf(buffer, " center:%d %d", srccp.x, srccp.y); // std::string text = buffer; // draw_str->strlist.push_back(text); // } // { // sprintf(buffer, " len %0.2f A: %0.2f ", pqx->len, pqx->area); // std::string text = buffer; // draw_str->strlist.push_back(text); // } // { // sprintf(buffer, " E:%0.2f hj %0.2f", pqx->energy, pqx->hj); // std::string text = buffer; // draw_str->strlist.push_back(text); // } sendTask(draw_str); // 在小图上绘制 { cv::Rect drawroi = pqx->CutImgroi; cv::Point cp = cv::Point(drawroi.x + drawroi.width * .5, drawroi.y + drawroi.height * 0.5); int r = drawroi.width; if (drawroi.height > r) { r = drawroi.height; } r += 10; std::shared_ptr draw_qx_small = std::make_shared(); draw_qx_small->drawImg = pqx->srcImg; draw_qx_small->cp = cp; draw_qx_small->dr = r; draw_qx_small->color = color_Ys; draw_qx_small->type = Draw_circle; sendTask(draw_qx_small); std::shared_ptr draw_str_small = std::make_shared(); draw_str_small->drawImg = pqx->srcImg; draw_str_small->type = Draw_str; draw_str_small->color = color_Ys; draw_str_small->txtP = cp; draw_str_small->cp = cp; draw_str_small->strlist.assign(draw_str->strlist.begin(), draw_str->strlist.end()); draw_str_small->txtsize = 0.45; sendTask(draw_str_small); } } std::shared_ptr pDetResult = pImageResult->pDetResult; // 检测结果 int qxNum = pDetResult->pQx_ErrorList->size(); for (int qxidx = 0; qxidx < qxNum; qxidx++) { QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx); // 只绘制 未分析 或分析失败的。 if (QX_info->result != QX_RESULT_TYPE_NoJduge) { continue; } std::shared_ptr draw_qx = std::make_shared(); cv::Rect roi = QX_info->roi; cv::Rect drawroi; drawroi.x = roi.x * fs_resize_x; drawroi.width = roi.width * fs_resize_x; drawroi.y = roi.y * fs_resize_y; drawroi.height = roi.height * fs_resize_y; cv::Point cp = cv::Point(drawroi.x + drawroi.width * .5, drawroi.y + drawroi.height * 0.5); int r = drawroi.width; if (drawroi.height > r) { r = drawroi.height; } r += 10; draw_qx->cp = cp; draw_qx->dr = r; draw_qx->color = color_Nojudge; draw_qx->drawImg = m_CheckResult_shareP->resultimg; draw_qx->type = Draw_circle; sendTask(draw_qx); std::shared_ptr draw_str = std::make_shared(); draw_str->drawImg = m_CheckResult_shareP->resultimg; draw_str->type = Draw_str; draw_str->color = color_Nojudge; draw_str->cp = cp; draw_str->txtP = cv::Point(draw_qx->cp.x + r, draw_qx->cp.y - r); draw_str->txtbackgroundk = txtbackgroundk; draw_str->txtsize = 0.5; char buffer[128]; { std::string text = std::to_string(QX_info->Idx); draw_str->strlist.push_back(text); } sendTask(draw_str); } long t2 = CheckUtil::getcurTime(); // 等待绘制完成 WaiteDrawComplate(); long t3 = CheckUtil::getcurTime(); // printf("=====draw=all %ld send %ld wait %ld \n", t3 - t1, t2 - t1, t3 - t2); return 0; } int ImageResultJudge::GetParamidx() { int region = 0; if (m_pCommonAnalysisyConfig == NULL || 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; } int ImageResultJudge::ConfigTypeToResultType(int nconfigType) { // 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) // ERROR_TYPE_OK, // 0 疑是 // ERROR_TYPE_AD_YX, // 1 AD-异常显示 // ERROR_TYPE_Line_X, // 2 x line // ERROR_TYPE_Line_Y, // 3 y line // ERROR_TYPE_Rubbing_Mura, // 4 // ERROR_TYPE_line_Broken, // 5 断线 // ERROR_TYPE_ZARA, // 6 ZARA // ERROR_TYPE_MTX, // 7 MTX // ERROR_TYPE_POL_Cell, // 8 异物 // ERROR_TYPE_LD, // 9 亮点 // ERROR_TYPE_AD, // 10 暗点 // ERROR_TYPE_BD, // 11 黑点 // ERROR_TYPE_WD, // 12 白点 // ERROR_TYPE_Scratch, // 13 划伤 // ERROR_TYPE_Weak_Bright_Mura, // 14 白GAP // ERROR_TYPE_No_Label, // 15 缺POL // ERROR_TYPE_PS, // 16 PS // ERROR_TYPE_GRID_LINE, // 17 方格线 // ERROR_TYPE_STEAM_POCKET, // 19 气泡 // ERROR_TYPE_Dirty, // 19 脏污 int resultError_type = ERROR_TYPE_OK; switch (nconfigType) { case CONFIG_QX_NAME_ok_yisi: resultError_type = ERROR_TYPE_OK; break; case CONFIG_QX_NAME_AD_YX: resultError_type = ERROR_TYPE_AD_YX; break; case CONFIG_QX_NAME_Class_AD_YX: resultError_type = ERROR_TYPE_AD_YX; break; case CONFIG_QX_NAME_X_line: resultError_type = ERROR_TYPE_Line_X; break; case CONFIG_QX_NAME_Y_line: resultError_type = ERROR_TYPE_Line_Y; break; case CONFIG_QX_NAME_Fangge: resultError_type = ERROR_TYPE_Line_fangge; break; case CONFIG_QX_NAME_Broken_line: resultError_type = ERROR_TYPE_line_Broken; break; case CONFIG_QX_NAME_zara: resultError_type = ERROR_TYPE_ZARA; break; case CONFIG_QX_NAME_MTX: resultError_type = ERROR_TYPE_MTX; break; case CONFIG_QX_NAME_POL_Cell: resultError_type = ERROR_TYPE_POL_Cell; break; case CONFIG_QX_NAME_LD: resultError_type = ERROR_TYPE_LD; break; case CONFIG_QX_NAME_AD: resultError_type = ERROR_TYPE_AD; break; case CONFIG_QX_NAME_Scratch_L1: resultError_type = ERROR_TYPE_Scratch; break; case CONFIG_QX_NAME_Scratch_L2: resultError_type = ERROR_TYPE_Scratch; break; case CONFIG_QX_NAME_Dirty_L0: resultError_type = ERROR_TYPE_Dirty; break; case CONFIG_QX_NAME_Dirty_L1: resultError_type = ERROR_TYPE_Dirty; break; case CONFIG_QX_NAME_Dirty_L2: resultError_type = ERROR_TYPE_Dirty; break; case CONFIG_QX_NAME_qipao: resultError_type = ERROR_TYPE_STEAM_POCKET; break; case CONFIG_QX_NAME_PS: resultError_type = ERROR_TYPE_PS; break; case CONFIG_QX_NAME_Weak_Bright_Mura: resultError_type = ERROR_TYPE_Weak_Bright_Mura; break; case CONFIG_QX_NAME_No_Label: resultError_type = ERROR_TYPE_No_Label; break; case CONFIG_QX_NAME_Other: resultError_type = ERROR_TYPE_Other; break; case CONFIG_QX_NAME_Chess: resultError_type = ERROR_TYPE_Other; break; case CONFIG_QX_NAME_127Cell: resultError_type = ERROR_TYPE_POL_Cell; break; case CONFIG_QX_NAME_white_Cell: resultError_type = ERROR_TYPE_Cell_W; break; case CONFIG_QX_NAME_black_Cell: resultError_type = ERROR_TYPE_Cell_B; break; case CONFIG_QX_NAME_LackPOL: resultError_type = ERROR_TYPE_LackPol; break; default: break; } return resultError_type; return 0; } int ImageResultJudge::sendTask(std::shared_ptr task) { { std::lock_guard lock(m_task_mutex_); m_DrawInfoList.push(task); } m_task_cv_.notify_one(); return 0; } std::shared_ptr ImageResultJudge::GetTask() { std::shared_ptr task; { std::unique_lock lock(m_task_mutex_); m_task_cv_.wait(lock, [this]() { return !m_DrawInfoList.empty(); }); task = std::move(m_DrawInfoList.front()); m_DrawInfoList.pop(); } return task; } void ImageResultJudge::ThreadDraw() { while (!m_bExit) { std::this_thread::sleep_for(std::chrono::milliseconds(0)); // 等待是否有任务 std::shared_ptr draw = GetTask(); // 把任务发送给对应的任务处理函数进行处理 DrawResultTask(draw); m_drawComplate_cv_.notify_all(); } } int ImageResultJudge::DrawResultTask(std::shared_ptr task) { if (task->type == Draw_circle) { cv::circle(task->drawImg, task->cp, task->dr, task->color); if (task->txtbackgroundk) { task->txtbackgroundk->txtDrawRoi.push_back(task->roi); } } if (task->type == Draw_rect) { cv::rectangle(task->drawImg, task->roi, task->color); if (task->txtbackgroundk) { task->txtbackgroundk->txtDrawRoi.push_back(task->roi); } } if (task->type == Draw_str) { int fontFace = cv::FONT_HERSHEY_SIMPLEX; double fontScale = task->txtsize; int thickness = 0.5; int baseline = 0; // 行高(根据字体大小计算) int txtH = cv::getTextSize("Test", fontFace, fontScale, thickness, &baseline).height; int lineHeight = txtH + 5; // 起始位置 int x = task->txtP.x; int y = task->txtP.y; int height = 0; int maxw = 0; for (const auto &txt : task->strlist) { // 计算文本大小 cv::Size textSize = cv::getTextSize(txt, fontFace, fontScale, thickness, &baseline); if (textSize.width > maxw) { maxw = textSize.width; } height += lineHeight; // 下一行 } cv::Rect rtxt = cv::Rect(x, y - txtH, maxw, height); cv::Rect r = cv::Rect(x, y, maxw, height); if (task->txtbackgroundk) { cv::Rect newr = task->txtbackgroundk->findNonOverlappingPos(rtxt); task->txtbackgroundk->txtDrawRoi.push_back(newr); rtxt = newr; r = rtxt; r.y += txtH; } // 左边界 if (r.x < 0) r.x = 0; // 上边界 if (r.y < 0) r.y = 0; // 右边界 if (r.x + r.width > task->drawImg.cols) r.x = task->drawImg.cols - r.width; // 下边界 if (r.y + r.height > task->drawImg.rows) r.y = task->drawImg.rows - r.height; height = 0; for (const auto &txt : task->strlist) { // 画文字 cv::putText(task->drawImg, txt, cv::Point(r.x, r.y + height), fontFace, fontScale, task->color, thickness); height += lineHeight; // 下一行 } // cv::rectangle(task->drawImg, rtxt, cv::Scalar(255, 0, 0)); cv::Point p(r.x, r.y); if (task->cp.x - r.x > 30 || task->cp.y - r.y > 30) { cv::line(task->drawImg, p, task->cp, cv::Scalar(80, 0, 200)); } // cv::circle(task->drawImg, task->cp, 3, task->color); } return 0; } int ImageResultJudge::WaiteDrawComplate() { { std::unique_lock lock(m_task_mutex_); m_drawComplate_cv_.wait(lock, [this]() { return m_DrawInfoList.empty(); }); } return 0; } int ImageResultJudge::AnalysisResult_Pre(QX_ERROR_INFO_ *QX_info) { std::shared_ptr pQxLog = QX_info->detlog; int count = QX_info->detRegionidxList.size(); if (count <= 1) { return 0; } int regionNum = m_pCommonAnalysisyConfig->regionConfigArr.size(); // pQxLog->bPrintStr = true; cv::Rect roi = QX_info->roi; float JudgArea = QX_info->JudgArea; float JudgArea_second = QX_info->JudgArea_second; float flen = QX_info->flen; float grayDis = QX_info->grayDis; int energy = QX_info->energy; float fupS = QX_info->fUpIou; int maxValue = QX_info->maxValue; float density = QX_info->density; int QX_whiteBLACK = QX_info->whiteOrBlack; int config_qx_type = QX_info->nconfig_qx_type; QX_Stauts qx_status = QX_info->qx_status; std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type]; std::string qx_wb = WHITE_BLCAK_Names[QX_whiteBLACK]; std::string strdetRegionidxList = "num:" + to_string(QX_info->detRegionidxList.size()); for (int ij = 0; ij < count; ij++) { strdetRegionidxList += " " + to_string(QX_info->detRegionidxList[ij] + 1); } pQxLog->AddCheckstr(PrintLevel_1, "AnalysisResult_Pre", " region %s", strdetRegionidxList.c_str()); cv::Point pCenter; pCenter.x = roi.x + roi.width * 0.5; pCenter.y = roi.y + roi.height * 0.5; bool bNG_Status = false; bool bYS_Status = false; bool Judge_Status = false; QX_info->result = QX_RESULT_TYPE_NoJduge; bool bpre_use = false; bool bpre_reuslt = false; // 预处理是否通过。 bool bpre_succ = true; // 预处理是否成功 // 遍历当前区域所属的 区域进行参数判断。 for (auto iregion : QX_info->detRegionidxList) { // 只找到非0区域进行弱化处理 if (iregion == 0) { continue; } bpre_use = true; pQxLog->AddCheckstr(PrintLevel_2, "QX info", ">>>>>>>> region %d ", iregion + 1); // 1、判断当前区域是否要检测该通道画面。 // 2、基础的参数判断 if (iregion >= regionNum) { pQxLog->AddCheckstr(PrintLevel_3, "QX info", "Error regionIdx %d > param size %d ", iregion, regionNum); continue; } if (config_qx_type >= CONFIG_QX_NAME_count || config_qx_type < 0) { pQxLog->AddCheckstr(PrintLevel_3, "QX info", "Error def_type %d size %d ", config_qx_type, CONFIG_QX_NAME_count); continue; } int paramIdx = m_QxInParamListIdx[config_qx_type]; if (paramIdx < 0) { pQxLog->AddCheckstr(PrintLevel_3, "qx error", " paramIdx < 0 "); continue; } // 3、 基本参数判断 int checkFlage = 0; int nerrortype = 0; for (int ict = 0; ict < ANALYSIS_TYPE_COUNT; ict++) { if (ict == ANALYSIS_TYPE_YS) { continue; } std::string str_checkflag = "QX-check"; checkFlage = ict; CheckConfig_Regions_Param *pParam = &m_pCommonAnalysisyConfig->regionConfigArr.at(iregion).checkConfig_Regions_type[ict].checkConfig_Regions_Param.at(paramIdx); bool bUse = false; for (int j = 0; j < pParam->useNum; j++) { bool result = true; if (!pParam->paramArr[j].bEnable) { continue; } bUse = true; float At = pParam->paramArr[j].area; float Et = pParam->paramArr[j].energy; float hj = pParam->paramArr[j].hj; float Len = pParam->paramArr[j].length; float md = pParam->paramArr[j].density; bool bjudge = false; if (energy >= Et && JudgArea >= At && grayDis >= hj && flen >= Len && density >= md) { bjudge = true; } else { bpre_succ = false; // 没有通过预处理。 } pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "result", "%s param idx %d / %d", BOOL_TO_STR(bjudge), j + 1, pParam->useNum); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Area", "%s -> %f %s %f ", BOOL_TO_STR(JudgArea >= At), JudgArea, BOOL_TO_ThanLess(JudgArea >= At), At); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Energy", "%s -> %d %s %f ", BOOL_TO_STR(energy >= Et), energy, BOOL_TO_ThanLess(energy >= Et), Et); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "HJ", "%s -> %f %s %f ", BOOL_TO_STR(grayDis > hj), grayDis, BOOL_TO_ThanLess(grayDis > hj), hj); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Len", "%s -> %f %s %f ", BOOL_TO_STR(flen > Len), flen, BOOL_TO_ThanLess(flen > Len), Len); pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "md", "%s -> %f %s %f ", BOOL_TO_STR(density >= md), density, BOOL_TO_ThanLess(density >= md), md); // 没有通过预处理。退出下次参数判断 if (!bpre_succ) { pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "pre Judge", "check fail ,break "); break; } } // 没有通过弱化区验证 if (!bpre_succ) { break; // 没有通过预处理。退出下个 区域判断 } } // 没有通过弱化区验证 if (!bpre_succ) { break; // 没有通过预处理。退出下个 区域判断 } } int pre_result = 0; // 使用并且 没有通过预处理。 if (bpre_use && !bpre_succ) { pre_result = 1; pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "pre Judge", "check fail ,Stop Judge"); } else { pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "pre Judge", "check Succ ,Continue Judge"); } return pre_result; } ChannelCheckFunction *ImageResultJudge::GetChannelFuntion(std::string strChannelName) { ChannelCheckFunction *p = NULL; // printf("m_pChannelFuntion->channelFunctionArr.size() %zu\n", m_pChannelFuntion->channelFunctionArr.size()); for (int i = 0; i < m_pChannelFuntion->channelFunctionArr.size(); i++) { if (CheckUtil::compareIgnoreCase(m_pChannelFuntion->channelFunctionArr[i].strChannelName, strChannelName)) { p = &m_pChannelFuntion->channelFunctionArr[i]; } } return p; } int ImageResultJudge::ConfigTypeToQXAnalysis(int nconfigType) { int QXAnalysis_type = -1; switch (nconfigType) { case CONFIG_QX_NAME_POL_Cell: QXAnalysis_type = QX_ANALYSIS_POL_CELL; // 异物 break; case CONFIG_QX_NAME_AD: QXAnalysis_type = QX_ANALYSIS_AD; // 暗点 break; case CONFIG_QX_NAME_Scratch_L1: case CONFIG_QX_NAME_Scratch_L2: QXAnalysis_type = QX_ANALYSIS_Scratch; // 划伤 break; case CONFIG_QX_NAME_X_line: case CONFIG_QX_NAME_Y_line: case CONFIG_QX_NAME_line: case CONFIG_QX_NAME_Fangge: QXAnalysis_type = QX_ANALYSIS_LINE; // 线类 break; case CONFIG_QX_NAME_MTX: QXAnalysis_type = QX_ANALYSIS_MTX; // MTX break; // case CONFIG_QX_NAME_Broken_line: // QXAnalysis_type = QX_ANALYSIS_ALL, // MTX&异物 // break; default: QXAnalysis_type = -1; break; } return QXAnalysis_type; } int ImageResultJudge::SetInDetConfig(std::string strcameraName) { for (int i = 0; i < CONFIG_QX_NAME_count; i++) { 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); int qxidx = ConfigTypeToQXAnalysis(i); if (qxidx < 0) { continue; } if (i == CONFIG_QX_NAME_X_line || i == CONFIG_QX_NAME_Y_line || i == CONFIG_QX_NAME_Fangge) { continue; } for (int j = 0; j < pParam->useNum; j++) { bool result = true; if (!pParam->paramArr[j].bEnable) { continue; } QXAnalysis_Config temconfig; temconfig.area = pParam->paramArr[j].area; temconfig.dis = pParam->paramArr[j].dis; temconfig.num = pParam->paramArr[j].num; temconfig.len = pParam->paramArr[j].length; temconfig.hj = pParam->paramArr[j].hj; temconfig.density = pParam->paramArr[j].density; temconfig.bok = pParam->paramArr[j].bOk; temconfig.sum_area = pParam->paramArr[j].area_max; // if (pParam->paramArr[j].num > 0 || pParam->paramArr[j].dis > 0) // { // m_pQX_Merge_Analysis->SetConfig(strcameraName, qxidx, temconfig); // } } } // int paramIdx = m_QxInParamListIdx[config_qx_type]; // if (paramIdx < 0) // { // m_TemCheck.AddCheckstr(PrintLevel_0, DET_LOG_LEVEL_3, "qx error", " paramIdx < 0 "); // continue; // } // for (int ict = 0; ict < ANALYSIS_TYPE_COUNT; ict++) // { // std::string str_checkflag = "QX-check"; // checkFlage = ict; // if (ict == ANALYSIS_TYPE_YS) // { // str_checkflag = "YS-check"; // } // m_TemCheck.AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "info", " %s start", str_checkflag.c_str()); // CheckConfig_Regions_Param *pParam = &m_pRegionAnalysisyParam->checkConfig_Regions_type[ict].checkConfig_Regions_Param.at(paramIdx); return 0; } int ImageResultJudge::SetMergeConfig(std::string strcameraName) { m_pQX_Merge_Analysis->InitConfig(strcameraName); for (int i = 0; i < CONFIG_QX_NAME_count; i++) { 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); int qxidx = ConfigTypeToQXAnalysis(i); if (qxidx < 0) { continue; } if (i == CONFIG_QX_NAME_X_line || i == CONFIG_QX_NAME_Y_line || i == CONFIG_QX_NAME_Fangge) { continue; } for (int j = 0; j < pParam->useNum; j++) { bool result = true; if (!pParam->paramArr[j].bEnable) { continue; } QXAnalysis_Config temconfig; temconfig.area = pParam->paramArr[j].area; temconfig.dis = pParam->paramArr[j].dis; temconfig.num = pParam->paramArr[j].num; temconfig.len = pParam->paramArr[j].length; temconfig.hj = pParam->paramArr[j].hj; temconfig.density = pParam->paramArr[j].density; temconfig.bok = pParam->paramArr[j].bOk; temconfig.sum_area = pParam->paramArr[j].area_max; if (pParam->paramArr[j].num > 0 || pParam->paramArr[j].dis > 0) { m_pQX_Merge_Analysis->SetConfig(strcameraName, qxidx, temconfig); } } } return 0; }