diff --git a/AlgorithmModule/include/ImgCheckAnalysisy.hpp b/AlgorithmModule/include/ImgCheckAnalysisy.hpp index 834b9e9..7bc29e9 100644 --- a/AlgorithmModule/include/ImgCheckAnalysisy.hpp +++ b/AlgorithmModule/include/ImgCheckAnalysisy.hpp @@ -200,7 +200,7 @@ private: int BLobToDetResult(); //自适应参数区域更新 - int Adapt_Config(Mat img, Rect roi, bool b_update); + int Adapt_Config(Mat img, Rect cur_roi, cv::RotatedRect& rot_cur_roi, bool b_update); std::shared_ptr AI_Factory; diff --git a/AlgorithmModule/src/ImgCheckAnalysisy.cpp b/AlgorithmModule/src/ImgCheckAnalysisy.cpp index bf61a34..c245d26 100644 --- a/AlgorithmModule/src/ImgCheckAnalysisy.cpp +++ b/AlgorithmModule/src/ImgCheckAnalysisy.cpp @@ -181,7 +181,7 @@ int ImgCheckAnalysisy::GetStatus() std::string ImgCheckAnalysisy::GetVersion() { - return std::string("BOE_1.1.0"); + return std::string("BOE_1.2.0"); } std::string ImgCheckAnalysisy::GetErrorInfo() @@ -602,7 +602,7 @@ std::vector sort_vertices(cv::RotatedRect rrect) { return vertices; } -int ImgCheckAnalysisy::Adapt_Config(Mat img, Rect cur_roi, bool b_update){ +int ImgCheckAnalysisy::Adapt_Config(Mat img, Rect cur_roi, cv::RotatedRect& rot_cur_roi, bool b_update){ if (img.empty()) { std::cerr << "Error: Input image 'img' is empty!" << std::endl; return -1; @@ -610,7 +610,7 @@ int ImgCheckAnalysisy::Adapt_Config(Mat img, Rect cur_roi, bool b_update){ if(!b_update){ return 1; } - cv::RotatedRect rot_cur_roi; + // cv::RotatedRect rot_cur_roi; int get_edge_roi = GetEdgeRoi(img, cur_roi, rot_cur_roi, 20, 20); if(get_edge_roi != 0){ return 2; @@ -802,7 +802,7 @@ int ImgCheckAnalysisy::CheckRun() /*自适应更新参数*/ long time_adapt_s = CheckUtil::getcurTime(); cv::RotatedRect rot_cur_roi; - Adapt_Config(m_CheckResult_shareP->in_shareImage->img, m_CutRoi, m_pbaseCheckFunction->markLine.badapt_region); + Adapt_Config(m_CheckResult_shareP->in_shareImage->img, m_CutRoi, rot_cur_roi, m_pbaseCheckFunction->markLine.badapt_region); long time_adapt_e = CheckUtil::getcurTime(); m_pdetlog->AddCheckstr(PrintLevel_0, "Adapt_Config", "time = %ld", time_adapt_e - time_adapt_s); @@ -822,6 +822,8 @@ int ImgCheckAnalysisy::CheckRun() m_pdetlog->AddCheckstr(PrintLevel_0, "Edge", "Not Use AI_Edge %s", m_CheckResult_shareP->basicResult.strChannel.c_str()); m_CutRoi = cv::Rect(rot_cur_roi.boundingRect().x - 50 , rot_cur_roi.boundingRect().y - 50, rot_cur_roi.boundingRect().width + 100, rot_cur_roi.boundingRect().height + 100) & cv::Rect(0, 0, m_CheckResult_shareP->in_shareImage->img.cols, m_CheckResult_shareP->in_shareImage->img.rows); + m_pdetlog->AddCheckstr(PrintLevel_0, "Edge", "rot_cur_roi = [%d, %d, %d, %d]", rot_cur_roi.boundingRect().x, rot_cur_roi.boundingRect().y, rot_cur_roi.boundingRect().width, rot_cur_roi.boundingRect().height); + m_pdetlog->AddCheckstr(PrintLevel_0, "Edge", "CutRoi = [%d, %d, %d, %d]", m_CutRoi.x, m_CutRoi.y, m_CutRoi.width, m_CutRoi.height); } else { @@ -1068,7 +1070,48 @@ int ImgCheckAnalysisy::CalBlob_Other() 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; + blobs.blobTab[i].JudgArea = JudgArea; + float flen = roi.width * fs_x; + float fwid = roi.height * fs_x; + if (roi.height * fs_y > flen) + { + flen = roi.height * fs_y; + fwid = roi.width * fs_y; + } + blobs.blobTab[i].len = flen; + blobs.blobTab[i].breadth = fwid; + + // 长度 / 宽度 / 面积足够大的残点:跳过 calc_blob_info_withstats 与 + // Cal_QXLen 的昂贵精确计算,直接赋一个较大的值,避免大 ROI 耗时陡增。 + const int BIG_BLOB_LEN_PIXEL = 10000; // 长度或宽度阈值(像素) + const int BIG_BLOB_AREA_PIXEL = 10000 * 10000; // 面积阈值(像素) + const bool bBigBlob = (roi.width >= BIG_BLOB_LEN_PIXEL || + roi.height >= BIG_BLOB_LEN_PIXEL || + (long long)roi.width * roi.height >= BIG_BLOB_AREA_PIXEL); + + if (bBigBlob) + { + // 直接给较大的值,不再做精确计算 + blobs.blobTab[i].energy = 99999999; // 能量给较大值 + blobs.blobTab[i].grayDis = 255.0f; // 灰阶给较大值 + // 白/黑不参与精确计算,保持默认黑色;ERR_TYPE_2 强制黑色 + int QX_whiteBLACK = CONFIG_QX_BLACK; + if (blobs.blobTab[i].ErrType == ERR_TYPE_2) + { + QX_whiteBLACK = CONFIG_QX_BLACK; // 强制为 黑色 + } + blobs.blobTab[i].whiteOrblack = QX_whiteBLACK; + + printf("[CalBlob_Other] skip big blob %d roi %dx%d area %d\n", + i, roi.width, roi.height, blobs.blobTab[i].area); + continue; + } + + long t_blob_s = CheckUtil::getcurTime(); cv::Scalar result = calc_blob_info_withstats(m_pImageAllResult->detImg, m_pImageAllResult->AIMaskImg, roi); + long t_stats_e = CheckUtil::getcurTime(); int QX_whiteBLACK = CONFIG_QX_BLACK; if (result[0] > 0) @@ -1081,18 +1124,6 @@ int ImgCheckAnalysisy::CalBlob_Other() blobs.blobTab[i].energy = energe; blobs.blobTab[i].grayDis = hj; - float JudgArea = blobs.blobTab[i].area * fs_x * fs_y; - blobs.blobTab[i].JudgArea = JudgArea; - float flen = roi.width * fs_x; - float fwid = roi.height * fs_x; - if (roi.height * fs_y > flen) - { - flen = roi.height * fs_y; - fwid = roi.width * fs_y; - } - blobs.blobTab[i].len = flen; - blobs.blobTab[i].breadth = fwid; - int nerrortype = 0; int checkFlage = 0; @@ -1107,6 +1138,7 @@ int ImgCheckAnalysisy::CalBlob_Other() // 精确计算长度 vector re_len = Cal_QXLen(m_pImageAllResult->detImg(roi), config_qx_type, fs_x, fs_y); + long t_len_e = CheckUtil::getcurTime(); if (re_len.size() > 2) { @@ -1120,6 +1152,14 @@ int ImgCheckAnalysisy::CalBlob_Other() } } + + // 大 blob 耗时打印,便于定位大面积残点的性能瓶颈 + if (roi.width * roi.height > 100000) + { + printf("[CalBlob_Other] blob %d roi %dx%d area %d | stats %ldms QXLen %ldms\n", + i, roi.width, roi.height, blobs.blobTab[i].area, + t_stats_e - t_blob_s, t_len_e - t_stats_e); + } } return 0; } @@ -1854,7 +1894,7 @@ int ImgCheckAnalysisy::Traditional_Detect_Thread(const cv::Mat &img, cv::Mat &Re return -1; } - Base_Function_TraditionDet traditionParam = m_pbaseCheckFunction->traditionDet; // 首次调用时初始化传统检测参数(从 m_AnalysisyConfig 映射) + Base_Function_TraditionDet traditionParam = m_pbaseCheckFunction->traditionDet; { CHECK_PARAM cp; cp.nAreaLowFilter = 80;