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.
BOE_FOG_DETECT/AlgorithmModule/src/ImageResultJudge.cpp

1920 lines
56 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
float area_max = pParam->paramArr[j].area_max;
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( config_qx_type == CONFIG_QX_NAME_POL_Cell && area_max > 0)
{
if(detArea > area_max)
{
nerrortype = 0;
result = true;
bNG_Status = false;
bYS_Status = false;
}
pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "PolCell_Area_Max", "%s -> %f %s %f ",
BOOL_TO_STR(detArea > area_max), detArea, BOOL_TO_ThanLess(detArea > area_max), area_max);
}
// AD根据配置检测:未配置通道的AD缺陷不判NG
if (config_qx_type == CONFIG_QX_NAME_AD && m_pbaseCheckFunction && ict == ANALYSIS_TYPE_TF &&
std::find(m_pbaseCheckFunction->ad_check.analysis_sf.region_sf.begin(),
m_pbaseCheckFunction->ad_check.analysis_sf.region_sf.end(),
strChannel) == m_pbaseCheckFunction->ad_check.analysis_sf.region_sf.end())
{
nerrortype = 0;
result = true;
bNG_Status = false;
bYS_Status = false;
pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Param Judge", "AD channel %s not configured in region_sf", strChannel.c_str());
}
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;
bNG_Status = true;
}
}
// 暗点 3S 分析 对 好品 或者 是 疑是的缺陷进行3S分析。S数量分析。 3S的暗点直接NG.
if ((nerrortype == 0 || checkFlage != ANALYSIS_TYPE_TF) &&
config_qx_type == CONFIG_QX_NAME_AD && pFuntion != NULL && m_pbaseCheckFunction &&
m_pbaseCheckFunction->ad_check.bOpen &&
m_pbaseCheckFunction->ad_check.analysis_s.bOpen &&
m_pbaseCheckFunction->ad_check.analysis_s.NG_3s && bpreSucc)
{
bool b3sChannel = false;
if(std::find(m_pbaseCheckFunction->ad_check.analysis_sf.s_sf.begin(), m_pbaseCheckFunction->ad_check.analysis_sf.s_sf.end(), strChannel) != m_pbaseCheckFunction->ad_check.analysis_sf.s_sf.end())
{
b3sChannel = true;
}
Judge_Status = true;
int det_s_Vale = 0;
if (JudgArea >= m_pbaseCheckFunction->ad_check.S_standard_3s.area &&
flen >= m_pbaseCheckFunction->ad_check.S_standard_3s.len && b3sChannel)
{
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, m_pbaseCheckFunction->ad_check.S_standard_3s.area, m_pbaseCheckFunction->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, m_pbaseCheckFunction->ad_check.S_standard_3s.area, m_pbaseCheckFunction->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 != NULL && 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 != NULL && 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());
}
// 对于 AD_YX 类型,面积小于设定值的 降级为NoJudge
if (config_qx_type == CONFIG_QX_NAME_AD_YX && bYS_Status && pFuntion != NULL &&
pFuntion->function.f_YXDet.bOpen && JudgArea < pFuntion->function.f_YXDet.minArea)
{
bYS_Status = false;
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, "AD_YX downgrade", "area %f < %d, YS -> OK", JudgArea, pFuntion->function.f_YXDet.minArea);
}
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);
#ifdef SAVE_RESIMG
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);
#endif
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.srcImgroi.x += pDetResult->CutRoi.x;
tem.srcImgroi.y += pDetResult->CutRoi.y;
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;
}
#ifdef SAVE_RESIMG
GetAIDetImg(pImageResult, pCenter, tem.AI_in_Img, tem.AI_out_img);
#endif
m_CheckResult_shareP->qxImageResult.push_back(tem);
}
else
{
if (m_CheckResult_shareP->nYS_result <= ERROR_TYPE_OK)
{
m_CheckResult_shareP->nYS_result = nqx_type;
}
#ifdef SAVE_RESIMG
GetAIDetImg(pImageResult, pCenter, tem.AI_in_Img, tem.AI_out_img);
#endif
m_CheckResult_shareP->YS_ImageResult.push_back(tem);
}
pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, " result ", " name %s ---code %s", tem.strTypeName.c_str(), tem.qx_Code.c_str());
}
// 对于大面积 的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());
}
}
// 关联通道分析:登记脏污(dirty)缺陷位置,供 AD 绑定分析判断关联通道是否存在重叠脏污缺陷
if (config_qx_type == CONFIG_QX_NAME_Dirty_L0 ||
config_qx_type == CONFIG_QX_NAME_Dirty_L1 ||
config_qx_type == CONFIG_QX_NAME_Dirty_L2)
{
QX_Merge_Analysis::Correlated_Qx_Info_ corr_qx;
corr_qx.channel_name = pImageResult->strChannel;
corr_qx.camera_name = pImageResult->cameraBaseResult->strCameraName;
corr_qx.config_qx_type = config_qx_type;
corr_qx.result_type = ConfigTypeToResultType(config_qx_type);
corr_qx.product_roi = roi;
corr_qx.product_roi.x += fproduct_offx_piexl;
bool bAddCorr = m_pQX_Merge_Analysis->AddCorrelatedQxInfo(corr_qx, pQxLog);
pQxLog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, " Use Num And Dis Judge ", "qx %s ,Add Correlated %s %s",
qx_name.c_str(), BOOL_TO_STR_Error(bAddCorr), corr_qx.GetInfo().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->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);
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);
#ifdef SAVE_RESIMG
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);
#endif
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.srcImgroi.x += pDetResult->CutRoi.x;
tem.srcImgroi.y += pDetResult->CutRoi.y;
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;
}
#ifdef SAVE_RESIMG
GetAIDetImg(pImageResult, pCenter, tem.AI_in_Img, tem.AI_out_img);
#endif
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)
{
bool bdesc = false;
int resultError_type = ERROR_TYPE_OK;
if(nconfigType < CONFIG_QX_NAME_Names.size())
{
string cqn = CONFIG_QX_NAME_Names[nconfigType];
for(int i = 0; i < m_FlawCodeList.size(); i++)
{
for(int j = 0; j < m_FlawCodeList.at(i).config_flaw_name.size(); j++)
{
if(cqn == m_FlawCodeList.at(i).config_flaw_name[j])
{
resultError_type = i;
bdesc = true;
break;
}
}
}
}
// 如果描述没有配置,用默认值
if(!bdesc)
{
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;
}
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;
}