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.

1234 lines
36 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;
}
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;
}
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; // 返回结果
int qxNum = pDetResult->pQx_ErrorList->size();
// map<string, vector<iregionQxZoningInfo>> allQxZoning;
map<string, vector<singleQxZoningInfo>> allQxZoning;
set<string> qx_name_list;
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 fbreadth = QX_info->fbreadth;
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;
std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type];
std::string qx_wb = WHITE_BLCAK_Names[QX_whiteBLACK];
pQxLog->AddCheckstr(PrintLevel_1,
"", "qxidx: %d roi[%d %d %d %d] qx %d %s %s JudgArea %f hj %f len %f breadth %f energy %d region num %ld",
qxidx, roi.x, roi.y, roi.width, roi.height, config_qx_type, qx_name.c_str(), qx_wb.c_str(),
JudgArea, grayDis, flen, fbreadth, energy, QX_info->detRegionidxList.size());
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;
allQxZoning[qx_name].reserve(20);
qx_name_list.insert(qx_name);
// 遍历当前区域所属的 区域进行参数判断。
for (auto iregion : QX_info->detRegionidxList)
{
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);
addInDrawBlob(config_qx_type, qxidx, QX_info, fs_resize_x, fs_resize_y);
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);
addInDrawBlob(config_qx_type, qxidx, QX_info, fs_resize_x, fs_resize_y);
continue;
}
int paramIdx = m_QxInParamListIdx[config_qx_type];
if (paramIdx < 0)
{
pQxLog->AddCheckstr(PrintLevel_3, "qx error", " paramIdx < 0 ");
addInDrawBlob(config_qx_type, qxidx, QX_info, fs_resize_x, fs_resize_y);
continue;
}
// 3、 基本参数判断
int checkFlage = 0;
int nerrortype = 0;
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";
}
// pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "qx judge", " %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)
{
// pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "error ", "param is CLosed");
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 Breadth = pParam->paramArr[j].breadth;
float md = pParam->paramArr[j].density;
float dis = pParam->paramArr[j].dis;
float num = pParam->paramArr[j].num;
if(dis > 0 && num > 0 && allQxZoning[qx_name].size() == 0){
pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "Dis | Num", "qx_name : %s, dis : %f, num : %f, scale_X : %f, scale_Y : %f",
qx_name.c_str(), dis, num, m_fImgage_Scale_X, m_fImgage_Scale_Y);
singleQxZoningInfo singleQxZoningInfoTemp;
singleQxZoningInfoTemp.Init();
singleQxZoningInfoTemp.judge_dis = dis;
singleQxZoningInfoTemp.judge_num = num;
singleQxZoningInfoTemp.scale_X = m_fImgage_Scale_X;
singleQxZoningInfoTemp.scale_Y = m_fImgage_Scale_Y;
allQxZoning[qx_name].push_back(singleQxZoningInfoTemp);
}
// 黑缺陷
if (QX_whiteBLACK == CONFIG_QX_WHITE)
{
// pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "param---", "qx :white");
if (hj >= 0 || Et >= 0)
{
pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "param ", "Error param idx %d / %d qx white hj %f and energ %f >0",
j + 1, pParam->useNum, hj, Et);
continue;
}
Et = std::abs(Et);
hj = std::abs(hj);
}
else
{
// pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "param---", "qx :blcak");
if (hj < 0 || Et < 0)
{
pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "param ", "Error param idx %d / %d qx blcak hj %f and energ %f < 0",
j + 1, pParam->useNum, hj, Et);
continue;
}
}
Judge_Status = true;
float detArea = JudgArea;
if (energy >= Et &&
detArea >= At &&
grayDis >= hj &&
flen >= Len &&
fbreadth >= Breadth)
{
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 B %f",
BOOL_TO_STROK(result), j + 1, pParam->useNum, At, Et, hj, Len, Breadth);
}
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 (fbreadth < Breadth)
{
pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, "Breadth", "%s -> %f %s %f ",
BOOL_TO_STR(fbreadth >= Breadth), fbreadth, BOOL_TO_ThanLess(fbreadth > Breadth), Breadth);
}
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());
}
}
// 已经NG 就不继续判断了。
if (bNG_Status)
{
break;
}
}
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;
int if_insert = false;
singleQxInfo current_YS_info(qxidx, QX_RESULT_TYPE_YS, pCenter);
for(int i = 0; i < allQxZoning[qx_name].size(); i++){
if(allQxZoning[qx_name][i].Insert(current_YS_info)){
if_insert = true;
break;
}
}
if(!if_insert && allQxZoning[qx_name].size() > 0){
singleQxZoningInfo newZoningInfoTemp;
newZoningInfoTemp.Init();
newZoningInfoTemp.judge_dis = allQxZoning[qx_name][0].judge_dis;
newZoningInfoTemp.judge_num = allQxZoning[qx_name][0].judge_num;
newZoningInfoTemp.center = pCenter;
newZoningInfoTemp.scale_X = m_fImgage_Scale_X;
newZoningInfoTemp.scale_Y = m_fImgage_Scale_Y;
newZoningInfoTemp.qxList.push_back(current_YS_info);
allQxZoning[qx_name].push_back(newZoningInfoTemp); // 插入失败,添加一个新分组
}
}
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, "10、Param Judge", "qx %s ,result = %s", qx_name.c_str(), resultType.c_str());
// 当前是好品
if (!bNG_Status)
{
// 大缺陷判断
if (m_pbaseCheckFunction->bigNG.bOpen)
{
bool berror = false;
if (config_qx_type >= 0 || config_qx_type < CONFIG_QX_NAME_count)
{
bool qx_config_open = m_pbaseCheckFunction->bigNG.qx[config_qx_type].bOpen;
float qx_config_area = m_pbaseCheckFunction->bigNG.qx[config_qx_type].fArea;
if (qx_config_open)
{
if (JudgArea > qx_config_area)
{
berror = true;
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 > qx_config_area), JudgArea, BOOL_TO_ThanLess(JudgArea > qx_config_area), qx_config_area);
}
else
{
pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, " big qx", "qx %s param close ", m_pbaseCheckFunction->bigNG.qx[config_qx_type].strname.c_str());
}
}
}
else
{
pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, " big qx", " param close ");
}
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, "12、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.srcImgroi.x += pDetResult->CutRoi.x;
tem.srcImgroi.y += pDetResult->CutRoi.y;
tem.len = flen;
tem.breadth = fbreadth;
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);
pQxLog->bPrintStr = true;
pQxLog->AddCheckstr(PrintLevel_4, DET_LOG_LEVEL_3, " result ", " ---name: %s ---code: %s ---srcImgroi.x: %d ---srcImgroi.y: %d\n", tem.strTypeName.c_str(), tem.qx_Code.c_str(), tem.srcImgroi.x, tem.srcImgroi.y);
pQxLog->bPrintStr = false;
}
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);
}
}
}
for (const auto& name : qx_name_list)
{
string qx_name = name;
for(int i = 0; i < allQxZoning[qx_name].size(); i++)
{
// 个数超过设定值YS改为NG
if(allQxZoning[qx_name][i].judgeNum()){
for(int j = 0; j < allQxZoning[qx_name][i].qxList.size(); j++)
{
int qxidx = allQxZoning[qx_name][i].qxList[j].qxidx;
cv::Point pCenter = allQxZoning[qx_name][i].qxList[j].pcenter;
QX_ERROR_INFO_ *QX_info = &pDetResult->pQx_ErrorList->at(qxidx);
std::shared_ptr<DetLog> pQxLog = pDetResult->pQx_ErrorList->at(qxidx).detlog;
pQxLog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "YS to NG", " name: %s, idx: %d | Index %d / %d > %d", qx_name.c_str(), qxidx, j + 1, allQxZoning[qx_name][i].qxList.size(), allQxZoning[qx_name][i].judge_num);
// 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 fbreadth = QX_info->fbreadth;
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;
std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type];
std::string qx_wb = WHITE_BLCAK_Names[QX_whiteBLACK];
QX_info->result = QX_RESULT_TYPE_NG;
QX_info->result_name = QX_RESULT_TYPE_Names[QX_info->result];
std::string resultType = QX_info->result_name;
m_CheckResult_shareP->nresult = 1;
// 生成图片
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.srcImgroi.x += pDetResult->CutRoi.x;
tem.srcImgroi.y += pDetResult->CutRoi.y;
tem.len = flen;
tem.breadth = fbreadth;
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;
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);
}
}
}
}
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::UpdateConfig()
{
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();
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, " 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, " breadth %0.2f A: %0.2f ", pqx->breadth, 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_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::addInDrawBlob(int errortype, int blobidx, QX_ERROR_INFO_ *QX_info, float fs_resize_x, float fs_resize_y)
{
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_cell_aotudian:
resultError_type = ERROR_TYPE_aotudian;
break;
case CONFIG_QX_NAME_cell_other:
resultError_type = ERROR_TYPE_other;
break;
case CONFIG_QX_NAME_cell_line:
resultError_type = ERROR_TYPE_line;
break;
case CONFIG_QX_NAME_cell_zangwu:
resultError_type = ERROR_TYPE_zangwu;
break;
case CONFIG_QX_NAME_cell_edge:
resultError_type = ERROR_TYPE_edge;
break;
case CONFIG_QX_NAME_cell_ymhs:
resultError_type = ERROR_TYPE_ymhs;
break;
case CONFIG_QX_NAME_cell_dianzhuang:
resultError_type = ERROR_TYPE_dianzhuang;
break;
case CONFIG_QX_NAME_cell_posun:
resultError_type = ERROR_TYPE_posun;
break;
case CONFIG_QX_NAME_cell_xianwei:
resultError_type = ERROR_TYPE_xianwei;
break;
case CONFIG_QX_NAME_cell_shuizi:
resultError_type = ERROR_TYPE_shuizi;
break;
case CONFIG_QX_NAME_cell_danban:
resultError_type = ERROR_TYPE_danban;
break;
case CONFIG_QX_NAME_cell_fuchen:
resultError_type = ERROR_TYPE_fuchen;
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;
}