|
|
|
|
@ -170,7 +170,7 @@ int ImgCheckAnalysisy::GetStatus()
|
|
|
|
|
|
|
|
|
|
std::string ImgCheckAnalysisy::GetVersion()
|
|
|
|
|
{
|
|
|
|
|
return std::string("BOE_1.2.0");
|
|
|
|
|
return std::string("BOE_1.2.8_" + std::string(__DATE__) + "_" + std::string(__TIME__));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string ImgCheckAnalysisy::GetErrorInfo()
|
|
|
|
|
@ -332,7 +332,7 @@ cv::Scalar ImgCheckAnalysisy::calc_blob_info_withstats(cv::Mat &img, const cv::M
|
|
|
|
|
|
|
|
|
|
// 计算 hj(差异图像大于0的像素均值)
|
|
|
|
|
// double hj = std::abs(fbk - fdet);
|
|
|
|
|
double hj = CheckUtil::CalHj(cimg, cmask, mean_bk.val[0]);
|
|
|
|
|
double hj = CheckUtil::CalHjWeighted(cimg, cmask, fbk, 2.0f);
|
|
|
|
|
|
|
|
|
|
int worb = 0;
|
|
|
|
|
if (fdet >= fbk)
|
|
|
|
|
@ -381,7 +381,7 @@ double ImgCheckAnalysisy::CalBlobHJ(cv::Mat &img, const cv::Mat &mask, cv::Rect
|
|
|
|
|
|
|
|
|
|
// 计算 hj(差异图像大于0的像素均值)
|
|
|
|
|
// double hj = std::abs(fbk - fdet);
|
|
|
|
|
double hj = CheckUtil::CalHj(cimg, cmask, fbk);
|
|
|
|
|
double hj = CheckUtil::CalHjWeighted(cimg, cmask, fbk, 2.0f);
|
|
|
|
|
static int kkk = 0;
|
|
|
|
|
|
|
|
|
|
unsigned char *pErrordata = (unsigned char *)cimg.data;
|
|
|
|
|
@ -518,6 +518,14 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
|
|
|
|
|
|
Edge_Det();
|
|
|
|
|
|
|
|
|
|
// BQ标签AI检测
|
|
|
|
|
{
|
|
|
|
|
long t_BQ_s = CheckUtil::getcurTime();
|
|
|
|
|
int recBQ = AI_Detect_BQ();
|
|
|
|
|
long t_BQ_e = CheckUtil::getcurTime();
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "4、BQ Detect", "-------------------------BQ AI Detect--------%ld ms-------\n", t_BQ_e - t_BQ_s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_CheckResult_shareP->resultMaskImg = m_pImageAllResult->qx_DetAIResult->AI_MaskImg;
|
|
|
|
|
|
|
|
|
|
// cv::imwrite("dddddddd.png", m_pImageAllResult->qx_DetAIResult->AI_MaskImg);
|
|
|
|
|
@ -589,6 +597,7 @@ int ImgCheckAnalysisy::SetNewConfig()
|
|
|
|
|
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());
|
|
|
|
|
@ -666,6 +675,8 @@ int ImgCheckAnalysisy::Run(int nId)
|
|
|
|
|
CheckRun();
|
|
|
|
|
m_nRun_Status = CHECK_THREAD_STATUS_COMPLETE;
|
|
|
|
|
m_pImageAllResult->setStep(ImageAllResult::DetStep_Complet);
|
|
|
|
|
// ✅ 处理完成后立即释放 ImageAllResult 的中间数据,减少内存占用
|
|
|
|
|
m_pImageAllResult->ReleaseIntermediateData();
|
|
|
|
|
m_nRun_Status = CHECK_THREAD_STATUS_IDLE;
|
|
|
|
|
// printf("*--------%d\n", m_nRun_Status);
|
|
|
|
|
}
|
|
|
|
|
@ -1448,6 +1459,9 @@ int ImgCheckAnalysisy::GetCheckResultBLob()
|
|
|
|
|
|
|
|
|
|
BLobToDetResult();
|
|
|
|
|
|
|
|
|
|
// 计算缺陷密度
|
|
|
|
|
CalBlobDensity_QX();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1691,6 +1705,8 @@ int ImgCheckAnalysisy::GetALLBlob()
|
|
|
|
|
re = GetBlob_QX();
|
|
|
|
|
long t4 = CheckUtil::getcurTime();
|
|
|
|
|
re = GetBlob_127cell();
|
|
|
|
|
long t5 = CheckUtil::getcurTime();
|
|
|
|
|
re = GetBlob_BQ();
|
|
|
|
|
|
|
|
|
|
if (blobs.blobCount > 100)
|
|
|
|
|
{
|
|
|
|
|
@ -1700,8 +1716,8 @@ int ImgCheckAnalysisy::GetALLBlob()
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
"---GetALLBlob End ;use time %ld ms yx %ld ms lack %ld ms qx %ld ms 127 %ld ms bq %ld ms",
|
|
|
|
|
te - t1, t2 - t1, t3 - t2, t4 - t3, t5 - t4, te - t5);
|
|
|
|
|
|
|
|
|
|
// getchar();
|
|
|
|
|
return 0;
|
|
|
|
|
@ -1757,6 +1773,10 @@ int ImgCheckAnalysisy::GetBLob_YX()
|
|
|
|
|
cv::findContours(erodedImage, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
|
|
|
|
|
int nresult = 0;
|
|
|
|
|
|
|
|
|
|
// 将 mask 一次性 resize 到 detImg 尺寸,避免循环内反复 resize
|
|
|
|
|
cv::Mat maskImg;
|
|
|
|
|
cv::resize(erodedImage, maskImg, cv::Size(m_pImageAllResult->detImg.cols, m_pImageAllResult->detImg.rows), 0, 0, cv::INTER_AREA);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < contours.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
@ -1774,7 +1794,15 @@ int ImgCheckAnalysisy::GetBLob_YX()
|
|
|
|
|
|
|
|
|
|
roi.y *= fy_src;
|
|
|
|
|
roi.height *= fy_src;
|
|
|
|
|
float len = std::sqrt(roi.width * roi.width + roi.height * roi.height);
|
|
|
|
|
|
|
|
|
|
// 精确计算长度
|
|
|
|
|
float re_len = Cal_QXLen(maskImg(roi), config_qx_type, fx_src, fy_src);
|
|
|
|
|
|
|
|
|
|
cv::Scalar result = calc_blob_info_withstats(m_pImageAllResult->detImg, maskImg, 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);
|
|
|
|
|
|
|
|
|
|
if (true)
|
|
|
|
|
{
|
|
|
|
|
@ -1784,12 +1812,12 @@ int ImgCheckAnalysisy::GetBLob_YX()
|
|
|
|
|
temerror.area = area;
|
|
|
|
|
temerror.JudgArea = judgeArea;
|
|
|
|
|
temerror.JudgArea_second = judgeArea;
|
|
|
|
|
temerror.energy = area * fx_src * fy_src;
|
|
|
|
|
temerror.flen = len;
|
|
|
|
|
temerror.energy = result[1];
|
|
|
|
|
temerror.flen = re_len;
|
|
|
|
|
temerror.nconfig_qx_type = config_qx_type;
|
|
|
|
|
temerror.qx_name = qx_name;
|
|
|
|
|
temerror.maxValue = 0;
|
|
|
|
|
temerror.grayDis = 0;
|
|
|
|
|
temerror.maxValue = max_val;
|
|
|
|
|
temerror.grayDis = result[2];
|
|
|
|
|
temerror.density = 0;
|
|
|
|
|
temerror.fUpIou = 0;
|
|
|
|
|
|
|
|
|
|
@ -2139,6 +2167,199 @@ int ImgCheckAnalysisy::GetBlob_127cell()
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BQAI检测
|
|
|
|
|
int ImgCheckAnalysisy::AI_Detect_BQ()
|
|
|
|
|
{
|
|
|
|
|
std::string strBaseLog = "AI_Detect_BQ";
|
|
|
|
|
|
|
|
|
|
// 检查BQ标签AI检测是否启用
|
|
|
|
|
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result->bBQ_AI_Det)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int bqNum = static_cast<int>(m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_cropImages.size());
|
|
|
|
|
if (bqNum <= 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog, "============= Start, BQ num = %d", bqNum);
|
|
|
|
|
long ts = CheckUtil::getcurTime();
|
|
|
|
|
|
|
|
|
|
// 初始化BQ AI检测结果
|
|
|
|
|
m_pImageAllResult->bq_DetAIResult = std::make_shared<ImageAllResult::Image_AI_Det_Result>();
|
|
|
|
|
std::shared_ptr<ImageAllResult::Image_AI_Det_Result> pDetAIResult = m_pImageAllResult->bq_DetAIResult;
|
|
|
|
|
|
|
|
|
|
// 使用与主检测相同的AI模型(后续更改为BQ AI模型)
|
|
|
|
|
std::shared_ptr<AIModel_Base> pAI_Model = AI_Factory->AI_defect_Tag;
|
|
|
|
|
|
|
|
|
|
int AIInputImg_width = pAI_Model->input_0.width;
|
|
|
|
|
int AIInputImg_height = pAI_Model->input_0.height;
|
|
|
|
|
cv::Size modelInputSize(AIInputImg_width, AIInputImg_height);
|
|
|
|
|
|
|
|
|
|
// 创建全图大小的AI mask(与主检测detImg同尺寸)
|
|
|
|
|
cv::Mat AI_detImage = m_pImageAllResult->AI_detImg;
|
|
|
|
|
pDetAIResult->AI_MaskImg = cv::Mat::zeros(AI_detImage.size(), CV_8UC1);
|
|
|
|
|
|
|
|
|
|
// 先提交所有BQ AI推理任务(仿照AI_Detect_QX的提交-收集模式)
|
|
|
|
|
int submitted = 0;
|
|
|
|
|
int completed = 0;
|
|
|
|
|
while (completed < bqNum)
|
|
|
|
|
{
|
|
|
|
|
// 提交任务(限制并发数不超过2,避免占用过多资源)
|
|
|
|
|
if (submitted < bqNum && runner->GetProcessingCount() < 2)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat bqCrop = m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_cropImages.at(submitted);
|
|
|
|
|
if (!bqCrop.empty())
|
|
|
|
|
{
|
|
|
|
|
cv::Mat resizedCrop;
|
|
|
|
|
cv::resize(bqCrop, resizedCrop, modelInputSize);
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<AIMulThreadRunBase::AITask> task = std::make_shared<AIMulThreadRunBase::AITask>();
|
|
|
|
|
task->id = submitted;
|
|
|
|
|
task->roi = cv::Rect(0, 0, modelInputSize.width, modelInputSize.height);
|
|
|
|
|
task->input = resizedCrop;
|
|
|
|
|
task->output = std::make_shared<cv::Mat>();
|
|
|
|
|
task->engine = pAI_Model;
|
|
|
|
|
|
|
|
|
|
runner->SubmitTask(task);
|
|
|
|
|
}
|
|
|
|
|
submitted++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 收集已完成的结果
|
|
|
|
|
std::shared_ptr<AIMulThreadRunBase::AITask> result;
|
|
|
|
|
if (runner->PopResult(result))
|
|
|
|
|
{
|
|
|
|
|
int idx = result->id;
|
|
|
|
|
if (idx >= 0 && idx < bqNum)
|
|
|
|
|
{
|
|
|
|
|
cv::Rect bqRoi = m_pImageAllResult->cameraBaseResult->pBQ_Result->pBQ_expandedRoiList.at(idx);
|
|
|
|
|
cv::Rect validRoi = bqRoi & cv::Rect(0, 0, AI_detImage.cols, AI_detImage.rows);
|
|
|
|
|
|
|
|
|
|
if (validRoi.width > 0 && validRoi.height > 0)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat &outMask = *(result->output);
|
|
|
|
|
if (!outMask.empty())
|
|
|
|
|
{
|
|
|
|
|
// 将AI输出mask resize回BQ裁剪图原始尺寸
|
|
|
|
|
cv::Mat resizedMask;
|
|
|
|
|
cv::resize(outMask, resizedMask, cv::Size(bqRoi.width, bqRoi.height));
|
|
|
|
|
|
|
|
|
|
// 将BQ的mask结果放到全图mask的对应位置
|
|
|
|
|
resizedMask.copyTo(pDetAIResult->AI_MaskImg(validRoi), resizedMask);
|
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ[%d] AI done, roi=[%d,%d,%d,%d]",
|
|
|
|
|
idx, validRoi.x, validRoi.y, validRoi.width, validRoi.height);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "BQ[%d] AI output empty", idx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
completed++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long te = CheckUtil::getcurTime();
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog, "============= End, time=%ld ms", te - ts);
|
|
|
|
|
|
|
|
|
|
// 调试存图
|
|
|
|
|
if (DetImgInfo_shareP->bDebugsaveImg)
|
|
|
|
|
{
|
|
|
|
|
cv::imwrite(m_strCurDetCamChannel + "_AI_BQ_mask.png", pDetAIResult->AI_MaskImg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ImgCheckAnalysisy::GetBlob_BQ()
|
|
|
|
|
{
|
|
|
|
|
std::string strBaseLog = "GetBlob_BQ";
|
|
|
|
|
|
|
|
|
|
// 检查BQ标签AI检测是否启用
|
|
|
|
|
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!m_pImageAllResult->cameraBaseResult->pBQ_Result->bBQ_AI_Det)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!m_pImageAllResult->bq_DetAIResult)
|
|
|
|
|
{
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "bq_DetAIResult is null, skip");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<ImageAllResult::Image_AI_Det_Result> pDetAIResult = m_pImageAllResult->bq_DetAIResult;
|
|
|
|
|
cv::Mat maskimg = pDetAIResult->AI_MaskImg;
|
|
|
|
|
if (maskimg.empty())
|
|
|
|
|
{
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, strBaseLog, "AI_MaskImg is empty, skip");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long t1 = CheckUtil::getcurTime();
|
|
|
|
|
|
|
|
|
|
// 使用与主流程相同的blob提取方式:GetBlobs_V3
|
|
|
|
|
// BQ检测的mask中,缺陷像素值为非零值
|
|
|
|
|
ERROR_DOTS_BLOBS blobs_bq;
|
|
|
|
|
memset(&blobs_bq, 0x00, sizeof(ERROR_DOTS_BLOBS));
|
|
|
|
|
|
|
|
|
|
unsigned char *pGrayErrordata = (unsigned char *)maskimg.data;
|
|
|
|
|
int width = maskimg.cols;
|
|
|
|
|
int height = maskimg.rows;
|
|
|
|
|
int minArea = 10; // BQ标签区域最小缺陷面积阈值
|
|
|
|
|
|
|
|
|
|
// 使用逐像素扫描方式提取blob(GetBlobs_V3对mask中的非零值进行blob提取)
|
|
|
|
|
GetBlobs_V3(&blobs_bq, pGrayErrordata, width, height, minArea);
|
|
|
|
|
|
|
|
|
|
// 设置BQ blob的默认缺陷类型(后续分类会重新确定类型)
|
|
|
|
|
// 使用非cell类型,确保进入AI_Classify_New分类流程
|
|
|
|
|
for (int i = 0; i < blobs_bq.blobCount; i++)
|
|
|
|
|
{
|
|
|
|
|
blobs_bq.blobTab[i].ErrType = CONFIG_QX_NAME_LD; // 以亮点作为初始类型,后续分类修正
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将BQ的blob汇入主blob列表
|
|
|
|
|
PushBlob(&blobs, &blobs_bq);
|
|
|
|
|
|
|
|
|
|
long te = CheckUtil::getcurTime();
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, strBaseLog,
|
|
|
|
|
"BQ blob num = %d, merged to main blobs (total=%d), time=%ld ms",
|
|
|
|
|
blobs_bq.blobCount, blobs.blobCount, te - t1);
|
|
|
|
|
|
|
|
|
|
// 调试存图
|
|
|
|
|
if (DetImgInfo_shareP->bDebugsaveImg && blobs_bq.blobCount > 0)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat tm;
|
|
|
|
|
cv::cvtColor(maskimg, tm, cv::COLOR_GRAY2RGB);
|
|
|
|
|
for (int i = 0; i < blobs_bq.blobCount; i++)
|
|
|
|
|
{
|
|
|
|
|
cv::Rect roi;
|
|
|
|
|
roi.x = blobs_bq.blobTab[i].minx;
|
|
|
|
|
roi.y = blobs_bq.blobTab[i].miny;
|
|
|
|
|
roi.width = blobs_bq.blobTab[i].maxx - blobs_bq.blobTab[i].minx + 1;
|
|
|
|
|
roi.height = blobs_bq.blobTab[i].maxy - blobs_bq.blobTab[i].miny + 1;
|
|
|
|
|
cv::rectangle(tm, roi, cv::Scalar(0, 0, 255), 2);
|
|
|
|
|
}
|
|
|
|
|
cv::imwrite(m_strCurDetCamChannel + "_BQ_blob.png", tm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ImgCheckAnalysisy::AIMaskDet()
|
|
|
|
|
{
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "AIMaskDet", "=======start");
|
|
|
|
|
@ -2482,6 +2703,11 @@ int ImgCheckAnalysisy::AI_Detect_QX()
|
|
|
|
|
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");
|
|
|
|
|
@ -3351,23 +3577,40 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool bLD_Standard = false; // 是否通过LD标准判定(跳过UP/DP的IOU检查)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type];
|
|
|
|
|
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;
|
|
|
|
|
int dbresult = -1;
|
|
|
|
|
if(m_pFuntion->function.f_LDConfig.bOpen && m_pFuntion->function.f_LDConfig.bUseLD_Standard)
|
|
|
|
|
{
|
|
|
|
|
if(blobs.blobTab[i].JudgArea >= m_pFuntion->function.f_LDConfig.fLD_Area &&
|
|
|
|
|
blobs.blobTab[i].grayDis >= m_pFuntion->function.f_LDConfig.fLD_HJ &&
|
|
|
|
|
blobs.blobTab[i].energy >= m_pFuntion->function.f_LDConfig.fLD_En &&
|
|
|
|
|
blobs.blobTab[i].len >= m_pFuntion->function.f_LDConfig.fLD_Len)
|
|
|
|
|
{
|
|
|
|
|
dbresult = 1;
|
|
|
|
|
bLD_Standard = true;
|
|
|
|
|
}
|
|
|
|
|
pQxlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "LD Analysis", "Area %0.2f > %0.2f , hj %0.2f > %0.2f , Energy %0.2f > %0.2f , len %0.2f > %0.2f",
|
|
|
|
|
blobs.blobTab[i].JudgArea, m_pFuntion->function.f_LDConfig.fLD_Area, blobs.blobTab[i].grayDis, m_pFuntion->function.f_LDConfig.fLD_HJ, blobs.blobTab[i].energy, m_pFuntion->function.f_LDConfig.fLD_En, blobs.blobTab[i].len, m_pFuntion->function.f_LDConfig.fLD_Len);
|
|
|
|
|
}
|
|
|
|
|
if(dbresult != 1)
|
|
|
|
|
{
|
|
|
|
|
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_False(detre), qx_name.c_str());
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
@ -3428,8 +3671,8 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
|
|
|
|
|
|
QX_Stauts qx_status = QX_Stauts_Analysis;
|
|
|
|
|
|
|
|
|
|
// 和UP画面进行IOU判断
|
|
|
|
|
if (m_pFuntion->function.f_UseUpQX.bOpen)
|
|
|
|
|
// 和UP画面进行IOU判断 (通过亮点标准的缺陷跳过此检查)
|
|
|
|
|
if (!bLD_Standard && m_pFuntion->function.f_UseUpQX.bOpen)
|
|
|
|
|
{
|
|
|
|
|
if (fupS >= m_pFuntion->function.f_UseUpQX.fIOU)
|
|
|
|
|
{
|
|
|
|
|
@ -3441,6 +3684,10 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
|
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 if (bLD_Standard)
|
|
|
|
|
{
|
|
|
|
|
pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Up Mask judge", "bLD_Standard = true, skip UP/DP IOU check ;fupS = %0.2f ", fupS);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pQxlog->AddCheckstr(PrintLevel_2, DET_LOG_LEVEL_3, "Up Mask judge", "UseUpQX.bOpen = false ;fupS = %0.2f ", fupS);
|
|
|
|
|
@ -3450,7 +3697,7 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
|
bool ban = JudgeQXAnalysis(config_qx_type, pQxlog);
|
|
|
|
|
if (!ban)
|
|
|
|
|
{
|
|
|
|
|
std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type];
|
|
|
|
|
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());
|
|
|
|
|
|
|
|
|
|
@ -3467,7 +3714,7 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
|
isMarksheildQX = Judge_MarkLine_QX(config_qx_type, roi, pQxlog);
|
|
|
|
|
if (isMarksheildQX)
|
|
|
|
|
{
|
|
|
|
|
std::string qx_name = CONFIG_QX_NAME_Names[config_qx_type];
|
|
|
|
|
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());
|
|
|
|
|
|
|
|
|
|
@ -3496,6 +3743,7 @@ int ImgCheckAnalysisy::BLobToDetResult()
|
|
|
|
|
temerror.grayDis = blobs.blobTab[i].grayDis;
|
|
|
|
|
temerror.density = blobs.blobTab[i].density;
|
|
|
|
|
temerror.fUpIou = fupS;
|
|
|
|
|
temerror.bIsStandardLD = bLD_Standard;
|
|
|
|
|
temerror.whiteOrBlack = blobs.blobTab[i].whiteOrblack;
|
|
|
|
|
temerror.qx_status = qx_status;
|
|
|
|
|
|
|
|
|
|
@ -3738,11 +3986,13 @@ int ImgCheckAnalysisy::AI_Classify_New(const cv::Mat &src_Img, cv::Rect qx_roi,
|
|
|
|
|
|
|
|
|
|
if (3 != AI_detImage.channels())
|
|
|
|
|
{
|
|
|
|
|
cv::cvtColor(AI_detImage(task->roi), task->input, cv::COLOR_GRAY2BGR);
|
|
|
|
|
cv::Mat temsizeimg;
|
|
|
|
|
cv::resize(AI_detImage(task->roi), temsizeimg, sz);
|
|
|
|
|
cv::cvtColor(temsizeimg, task->input, cv::COLOR_GRAY2BGR);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
task->input = AI_detImage(task->roi).clone();
|
|
|
|
|
cv::resize(AI_detImage(task->roi), task->input, sz);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
task->engine = pAIDet;
|
|
|
|
|
@ -3756,6 +4006,12 @@ int ImgCheckAnalysisy::AI_Classify_New(const cv::Mat &src_Img, cv::Rect qx_roi,
|
|
|
|
|
if (runner->PopResult(result))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// if (true)
|
|
|
|
|
// {
|
|
|
|
|
// printf("result->cls_score %f\n",result->cls_score);
|
|
|
|
|
// std::string classpath = std::to_string(result->cls_label) + "_" + std::to_string(result->cls_score) + ".png";
|
|
|
|
|
// cv::imwrite(classpath, result->input);
|
|
|
|
|
// }
|
|
|
|
|
int cls_num = result->cls_label;
|
|
|
|
|
if (cls_num >= 0 && cls_num < maxcls)
|
|
|
|
|
{
|
|
|
|
|
@ -3884,6 +4140,7 @@ int ImgCheckAnalysisy::AI_Classify_New(const cv::Mat &src_Img, cv::Rect qx_roi,
|
|
|
|
|
if (true)
|
|
|
|
|
{
|
|
|
|
|
// 长宽比
|
|
|
|
|
bool bIsLine = false;
|
|
|
|
|
float flenr = 1;
|
|
|
|
|
int len = 0;
|
|
|
|
|
int widt = 0;
|
|
|
|
|
@ -3900,29 +4157,42 @@ int ImgCheckAnalysisy::AI_Classify_New(const cv::Mat &src_Img, cv::Rect qx_roi,
|
|
|
|
|
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)
|
|
|
|
|
// // 长宽比过大,判断成
|
|
|
|
|
// 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";
|
|
|
|
|
// bIsLine = true;
|
|
|
|
|
// }
|
|
|
|
|
// // 长宽比过小,判断成
|
|
|
|
|
// 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";
|
|
|
|
|
// bIsLine = true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
//长宽比满足,判断为线
|
|
|
|
|
if (flenr > 10)
|
|
|
|
|
{
|
|
|
|
|
// 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";
|
|
|
|
|
bIsLine = true;
|
|
|
|
|
}
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, DET_LOG_LEVEL_3, "AI_Classify_line", "bIsLine %d, flenr %f len %d,widt %d,fjustarea %f", bIsLine, flenr,len,widt,fjustarea);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -4432,4 +4702,105 @@ bool ImgCheckAnalysisy::JudgeQXAnalysis(int nqx_configType, std::shared_ptr<DetL
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ImgCheckAnalysisy::CalBlobDensity_QX()
|
|
|
|
|
{
|
|
|
|
|
float fs_x = m_fImgage_Scale_X;
|
|
|
|
|
float fs_y = m_fImgage_Scale_Y;
|
|
|
|
|
double dis_T = m_pBasicConfig->density_R_mm;
|
|
|
|
|
if (dis_T <= 0 || dis_T > 99999)
|
|
|
|
|
{
|
|
|
|
|
dis_T = 5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!m_pDetResult || !m_pDetResult->pQx_ErrorList || m_pDetResult->pQx_ErrorList->size() <= 0)
|
|
|
|
|
{
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, "Density_QX", "pQx_ErrorList is empty, skip density calc");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, "Density_QX", "Start: dis_T=%.1fmm qx_count=%zu", dis_T, m_pDetResult->pQx_ErrorList->size());
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < m_pDetResult->pQx_ErrorList->size(); i++)
|
|
|
|
|
{
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).density = 1;
|
|
|
|
|
|
|
|
|
|
if (m_pDetResult->pQx_ErrorList->at(i).nconfig_qx_type == CONFIG_QX_NAME_MTX ||
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).nconfig_qx_type == CONFIG_QX_NAME_POL_Cell ||
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).nconfig_qx_type == CONFIG_QX_NAME_LD ||
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).nconfig_qx_type == CONFIG_QX_NAME_AD)
|
|
|
|
|
{
|
|
|
|
|
/* code */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Rect roi = m_pDetResult->pQx_ErrorList->at(i).roi;
|
|
|
|
|
|
|
|
|
|
cv::Point p;
|
|
|
|
|
p.x = roi.x + roi.width * 0.5;
|
|
|
|
|
p.y = roi.y + roi.height * 0.5;
|
|
|
|
|
|
|
|
|
|
int num = 1;
|
|
|
|
|
double sum_dis = 0;
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < m_pDetResult->pQx_ErrorList->size(); j++)
|
|
|
|
|
{
|
|
|
|
|
if (i == j)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (m_pDetResult->pQx_ErrorList->at(j).nconfig_qx_type == CONFIG_QX_NAME_MTX ||
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(j).nconfig_qx_type == CONFIG_QX_NAME_POL_Cell ||
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(j).nconfig_qx_type == CONFIG_QX_NAME_LD ||
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(j).nconfig_qx_type == CONFIG_QX_NAME_AD)
|
|
|
|
|
{
|
|
|
|
|
/* code */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
cv::Rect roi123 = m_pDetResult->pQx_ErrorList->at(j).roi;
|
|
|
|
|
|
|
|
|
|
cv::Point p123;
|
|
|
|
|
p123.x = roi123.x + roi123.width * 0.5;
|
|
|
|
|
p123.y = roi123.y + roi123.height * 0.5;
|
|
|
|
|
|
|
|
|
|
double dis_x = std::abs(p123.x - p.x) * fs_x;
|
|
|
|
|
double dis_y = std::abs(p123.y - p.y) * fs_y;
|
|
|
|
|
double dis = std::sqrt(dis_x * dis_x + dis_y * dis_y);
|
|
|
|
|
if (dis > dis_T)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
num++;
|
|
|
|
|
sum_dis += dis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float avdis = dis_T;
|
|
|
|
|
if (num > 1)
|
|
|
|
|
{
|
|
|
|
|
avdis = sum_dis / (num - 1);
|
|
|
|
|
}
|
|
|
|
|
float fScore = (dis_T - avdis) / dis_T;
|
|
|
|
|
|
|
|
|
|
double fD = num + fScore;
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).density = fD;
|
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Density_QX", " idx=%d type=%d(%s) roi[%d,%d,%d,%d] near_num=%d avgDis=%.2f score=%.3f density=%.2f",
|
|
|
|
|
i,
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).nconfig_qx_type,
|
|
|
|
|
m_pDetResult->pQx_ErrorList->at(i).qx_name.c_str(),
|
|
|
|
|
roi.x, roi.y, roi.width, roi.height,
|
|
|
|
|
num, avdis, fScore, fD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, "Density_QX", "End: processed %zu defects", m_pDetResult->pQx_ErrorList->size());
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|