You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1871 lines
54 KiB

#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<ImageAllResult> 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<ImageAllResult> pImageResult)
{
std::shared_ptr<DetLog> 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<One_Image_CheckResult_> pDetResult = pImageResult->pDetResult; // 检测结果
std::shared_ptr<CheckResult> 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<DetLog> 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<CameraResult> 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<ImageAllResult> pImageResult, QX_Analysis_Result_List *ptemre)
{
std::shared_ptr<DetLog> 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<One_Image_CheckResult_> pDetResult = pImageResult->pDetResult; // 检测结果
std::shared_ptr<CheckResult> 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<DetLog> 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<ImageAllResult> pImageResult)
{
std::shared_ptr<txtDrawBackgroundk> txtbackgroundk = std::make_shared<txtDrawBackgroundk>();
if (!ptr_thread_Draw)
{
ptr_thread_Draw = std::make_shared<std::thread>(std::bind(&ImageResultJudge::ThreadDraw, this));
}
float fs_resize_x = pImageResult->fscale_detToresult_x;
float fs_resize_y = pImageResult->fscale_detToresult_x;
std::shared_ptr<CheckResult> m_CheckResult_shareP = pImageResult->result; // 返回结果
std::vector<cv::Rect> 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<DrawInfo> draw_qx = std::make_shared<DrawInfo>();
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<DrawInfo> draw_str = std::make_shared<DrawInfo>();
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<DrawInfo> draw_qx_small = std::make_shared<DrawInfo>();
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<DrawInfo> draw_str_small = std::make_shared<DrawInfo>();
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<DrawInfo> draw_qx = std::make_shared<DrawInfo>();
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<DrawInfo> draw_str = std::make_shared<DrawInfo>();
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<DrawInfo> draw_qx_small = std::make_shared<DrawInfo>();
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<DrawInfo> draw_str_small = std::make_shared<DrawInfo>();
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<One_Image_CheckResult_> 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<DrawInfo> draw_qx = std::make_shared<DrawInfo>();
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<DrawInfo> draw_str = std::make_shared<DrawInfo>();
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<DrawInfo> task)
{
{
std::lock_guard<std::mutex> lock(m_task_mutex_);
m_DrawInfoList.push(task);
}
m_task_cv_.notify_one();
return 0;
}
std::shared_ptr<ImageResultJudge::DrawInfo> ImageResultJudge::GetTask()
{
std::shared_ptr<DrawInfo> task;
{
std::unique_lock<std::mutex> 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<ImageResultJudge::DrawInfo> draw = GetTask();
// 把任务发送给对应的任务处理函数进行处理
DrawResultTask(draw);
m_drawComplate_cv_.notify_all();
}
}
int ImageResultJudge::DrawResultTask(std::shared_ptr<ImageResultJudge::DrawInfo> 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<std::mutex> 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<DetLog> 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;
}