update 传统检测优化过滤

dev_lsy
liusiyang 2 weeks ago
parent 0e72b46f87
commit 61f3682680

@ -420,7 +420,8 @@ int ALLImgCheckAnalysisy::InitData()
int ALLImgCheckAnalysisy::Det_Product(std::shared_ptr<Product> &product) int ALLImgCheckAnalysisy::Det_Product(std::shared_ptr<Product> &product)
{ {
string cur_time_s = CheckUtil::getCurTimeHMS();
printf("[%s]>>>>>>>>>>>>>>>Det_Product****************det Start************\n", cur_time_s.c_str());
// 处理每个相机 // 处理每个相机
while (true) while (true)
{ {
@ -449,8 +450,8 @@ int ALLImgCheckAnalysisy::Det_Product(std::shared_ptr<Product> &product)
// AnalysiyAll(0); // AnalysiyAll(0);
SetProductResult(product); SetProductResult(product);
product->SetCheckEnd(); product->SetCheckEnd();
string cur_time = CheckUtil::getCurTimeHMS(); string cur_time_e = CheckUtil::getCurTimeHMS();
printf("[%s]>>>>>>>>>>>>>>>Det_Product****************det End************\n", cur_time.c_str()); printf("[%s]>>>>>>>>>>>>>>>Det_Product****************det End************\n", cur_time_e.c_str());
return 0; return 0;
} }

@ -465,9 +465,12 @@ int GetEdgeRoi(Mat img, Rect &new_roi, cv::RotatedRect &rotated_roi, float scale
// 二值化找最大连通域 // 二值化找最大连通域
Mat r_img_bin; Mat r_img_bin;
threshold(r_img, r_img_bin, 15, 255, THRESH_BINARY); threshold(r_img, r_img_bin, 35, 255, THRESH_BINARY);
// 做一步闭运算
Mat r_img_bin_close;
morphologyEx(r_img_bin, r_img_bin_close, MORPH_CLOSE, Mat::ones(15, 15, CV_8U));
std::vector<std::vector<cv::Point>> contours; std::vector<std::vector<cv::Point>> contours;
cv::findContours(r_img_bin, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); cv::findContours(r_img_bin_close, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
if (contours.empty()) if (contours.empty())
{ {
return 2; return 2;
@ -779,7 +782,6 @@ int ImgCheckAnalysisy::CheckRun()
{ {
m_pdetlog->bPrintStr = true; m_pdetlog->bPrintStr = true;
} }
m_pdetlog->bPrintStr = true;
m_pdetlog->AddCheckstr(PrintLevel_0, "1、basic Info", "---------------------------1、basic Info---------------------------------"); 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, "Version", "%s", GetVersion().c_str());
@ -2509,9 +2511,43 @@ int ImgCheckAnalysisy::BLobToDetResult()
long t1 = CheckUtil::getcurTime(); long t1 = CheckUtil::getcurTime();
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "BLobToDetResult", " Start old qx num %ld", m_pDetResult->pQx_ErrorList->size()); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "BLobToDetResult", " Start old qx num %ld", m_pDetResult->pQx_ErrorList->size());
// 传统检测:按 nAreaFilter原图面积+ nCountFilter个数直接卡控最终上报。
// 对 blobs.blobTab 按面积降序,过滤 area <= nAreaFilter 的 blob再取前 nCountFilter 个。
// AI 路径bOpen=false不做此过滤保持原有全量上报。
const bool bTcsCountFilter = (m_pbaseCheckFunction != nullptr && m_pbaseCheckFunction->traditionDet.bOpen);
const float fAreaFilter = bTcsCountFilter ? m_pbaseCheckFunction->traditionDet.nAreaFilter : 0.0f;
const int nCountFilter = bTcsCountFilter ? m_pbaseCheckFunction->traditionDet.nCountFilter : blobs.blobCount;
int nFiltered = 0;
// 传统路径:构造按面积降序的索引,用于面积 + 个数卡控
std::vector<int> sortedIdx;
int nReport = blobs.blobCount; // 实际需要遍历上报的 blob 数量
if (bTcsCountFilter)
{
sortedIdx.resize(blobs.blobCount);
for (int j = 0; j < blobs.blobCount; j++) sortedIdx[j] = j;
std::sort(sortedIdx.begin(), sortedIdx.end(), [&](int a, int b) {
return blobs.blobTab[a].area > blobs.blobTab[b].area;
});
// 已按面积降序:第一个 area <= nAreaFilter 的 blob 即为有效区间终点
nReport = 0;
while (nReport < blobs.blobCount && blobs.blobTab[sortedIdx[nReport]].area > fAreaFilter)
{
nReport++;
}
if (nReport > nCountFilter)
{
nReport = nCountFilter;
}
nFiltered = blobs.blobCount - nReport;
}
// 遍历每个检测blob // 遍历每个检测blob
for (int i = 0; i < blobs.blobCount; i++) for (int idx = 0; idx < nReport; idx++)
{ {
const int i = bTcsCountFilter ? sortedIdx[idx] : idx;
cv::Rect roi; cv::Rect roi;
roi.x = blobs.blobTab[i].minx; roi.x = blobs.blobTab[i].minx;
roi.y = blobs.blobTab[i].miny; roi.y = blobs.blobTab[i].miny;
@ -2591,7 +2627,7 @@ int ImgCheckAnalysisy::BLobToDetResult()
} }
} }
long t2 = CheckUtil::getcurTime(); 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); m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "BLobToDetResult", " end qx num %ld filtered %d use time %ld", m_pDetResult->pQx_ErrorList->size(), nFiltered, t2 - t1);
return 0; return 0;
} }

@ -130,6 +130,7 @@ private:
void Process(bool bDraw = false); void Process(bool bDraw = false);
// 纯分类:对二值图做连通域分析+缺陷分类,结果写入 m_vecDefectInfo // 纯分类:对二值图做连通域分析+缺陷分类,结果写入 m_vecDefectInfo
// 面积/个数过滤已上移至 BLobToDetResult 统一处理,此处仅做缺陷类型打标签
void ClassifyBlobs(const cv::Mat& blurCrop, const cv::Mat& imgBlob); void ClassifyBlobs(const cv::Mat& blurCrop, const cv::Mat& imgBlob);
// 纯绘制:基于 m_vecDefectInfo 绘制缺陷标注 // 纯绘制:基于 m_vecDefectInfo 绘制缺陷标注
cv::Mat DrawBlobInfoImage(const cv::Mat& imgCrop, const cv::Mat& imgBlob); cv::Mat DrawBlobInfoImage(const cv::Mat& imgCrop, const cv::Mat& imgBlob);

@ -240,31 +240,14 @@ void CTcsCheck::ClassifyBlobs(const cv::Mat& blurCrop, const cv::Mat& imgBlob)
// logStep("1.连通域分析"); // logStep("1.连通域分析");
if (nLabels <= 1) return; if (nLabels <= 1) return;
struct BlobItem { int label; int area; }; // 大块缺陷的面积阈值(分类决策用,非过滤)
std::vector<BlobItem> blobs;
blobs.reserve(std::max(0, nLabels - 1));
for (int label = 1; label < nLabels; ++label) {
const int area = stats.at<int>(label, cv::CC_STAT_AREA);
if (area > m_cpCfg.nAreaFilter) {
blobs.push_back({ label, area });
}
}
// logStep("2.面积过滤");
if (blobs.empty()) return;
std::sort(blobs.begin(), blobs.end(), [](const BlobItem& a, const BlobItem& b) {
return a.area > b.area;
});
// logStep("3.面积排序");
// 大块缺陷的面积阈值
const int largeAreaThreshold = std::max(1, m_cpCfg.nBlockSize * m_cpCfg.nBlockSize / 4); const int largeAreaThreshold = std::max(1, m_cpCfg.nBlockSize * m_cpCfg.nBlockSize / 4);
const int topK = std::min(m_cpCfg.nCountFilter, static_cast<int>(blobs.size()));
for (int i = 0; i < topK; ++i) {
const int label = blobs[i].label;
const int area = blobs[i].area;
// 面积/个数过滤已统一上移到 BLobToDetResult 处理,
// 此处对所有连通域逐一分类,仅做缺陷类型打标签。
for (int label = 1; label < nLabels; ++label) {
const int area = stats.at<int>(label, cv::CC_STAT_AREA);
if (area < 5) continue;
// bounding rect // bounding rect
const int x = stats.at<int>(label, cv::CC_STAT_LEFT); const int x = stats.at<int>(label, cv::CC_STAT_LEFT);
const int y = stats.at<int>(label, cv::CC_STAT_TOP); const int y = stats.at<int>(label, cv::CC_STAT_TOP);

Loading…
Cancel
Save