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/ImgCheckAnalysisy.cpp

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