From 7460f61e2619cc6dfbf121a1129d362087bce324 Mon Sep 17 00:00:00 2001 From: liusiyang Date: Thu, 10 Sep 2026 18:03:22 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E6=9B=B4=E6=94=B9pin=E5=81=8F?= =?UTF-8?q?=E7=A7=BB=E7=BC=BA=E5=A4=B1=E5=88=A4=E6=96=AD=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AlgorithmModule/src/ImgCheckAnalysisy.cpp | 65 ++++++++++++++--------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/AlgorithmModule/src/ImgCheckAnalysisy.cpp b/AlgorithmModule/src/ImgCheckAnalysisy.cpp index 5971720..750a65f 100644 --- a/AlgorithmModule/src/ImgCheckAnalysisy.cpp +++ b/AlgorithmModule/src/ImgCheckAnalysisy.cpp @@ -1897,37 +1897,40 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img) if (nTpl > 0) { - // 1、统计模板 pin 中心与平均最小边长,用于自适应阈值 + // 1、统计模板 pin 中心与外包矩形 std::vector tplCenters(nTpl); - double sumMinDim = 0.0; + std::vector tplRects(nTpl); for (int i = 0; i < nTpl; i++) { tplCenters[i] = getCenter(m_tplPinContours[i]); - cv::Rect r = cv::boundingRect(m_tplPinContours[i]); - sumMinDim += (r.width < r.height) ? r.width : r.height; + tplRects[i] = cv::boundingRect(m_tplPinContours[i]); } - const float avgMinDim = static_cast(sumMinDim / nTpl); - // 偏移阈值约 1/4 个 pin 尺寸,缺失阈值约 3/4 个 pin 尺寸 - float offsetTh = avgMinDim * 0.5f; - if (offsetTh < 3.0f) - { - offsetTh = 3.0f; - } - float missTh = avgMinDim * 0.75f; - if (missTh < offsetTh + 1.0f) - { - missTh = offsetTh + 1.0f; - } - - // 2、当前 pin 中心 + // 2、当前 pin 中心与外包矩形 std::vector curCenters(nCur); + std::vector curRects(nCur); for (int i = 0; i < nCur; i++) { curCenters[i] = getCenter(m_curPinContours[i]); + curRects[i] = cv::boundingRect(m_curPinContours[i]); } std::vector curUsed(nCur, false); + // 3、偏移阈值由基础参数 pin_x_offset / pin_y_offset (mm) 换算为像素 + float offsetThX = 0.0f; + float offsetThY = 0.0f; + if (m_pbaseCheckFunction != NULL) + { + if (m_fImgage_Scale_X > 0.0f) + { + offsetThX = m_pbaseCheckFunction->pinDet.pin_x_offset / m_fImgage_Scale_X; + } + if (m_fImgage_Scale_Y > 0.0f) + { + offsetThY = m_pbaseCheckFunction->pinDet.pin_y_offset / m_fImgage_Scale_Y; + } + } + // 上报缺失/偏移缺陷(缺陷类型可按需调整) auto reportPinError = [&](int pinIdx, const cv::Point2f &tplCenter, const std::string &reason) { @@ -1954,7 +1957,7 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img) int nMiss = 0; int nOffset = 0; - // 3、逐个模板 pin 找最近且未被占用的当前 pin + // 4、逐个模板 pin 找与其相交且未被占用的当前 pin for (int i = 0; i < nTpl; i++) { int bestIdx = -1; @@ -1965,6 +1968,14 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img) { continue; } + + // 完全与模板没有相交 -> 不算候选 + cv::Rect inter = tplRects[i] & curRects[j]; + if (inter.width <= 0 || inter.height <= 0) + { + continue; + } + float dx = tplCenters[i].x - curCenters[j].x; float dy = tplCenters[i].y - curCenters[j].y; double d = std::sqrt(static_cast(dx) * dx + static_cast(dy) * dy); @@ -1975,8 +1986,8 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img) } } - // 无候选或距离过远 -> 缺失 - if (bestIdx < 0 || bestDist > missTh) + // 没有相交的当前 pin -> 缺失 + if (bestIdx < 0) { nMiss++; reportPinError(i, tplCenters[i], "miss"); @@ -1986,14 +1997,18 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img) curUsed[bestIdx] = true; - // 距离超出偏移阈值 -> 偏移 - if (bestDist > offsetTh) + // x 或 y 方向偏移超过配置阈值 -> 偏移 + float dx = tplCenters[i].x - curCenters[bestIdx].x; + float dy = tplCenters[i].y - curCenters[bestIdx].y; + float absDx = std::fabs(dx); + float absDy = std::fabs(dy); + if (absDx > offsetThX || absDy > offsetThY) { nOffset++; char buf[64]; - snprintf(buf, sizeof(buf), "offset %.1fpx", bestDist); + snprintf(buf, sizeof(buf), "offset dx %.1f dy %.1f", absDx, absDy); reportPinError(i, tplCenters[i], buf); - m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "pin %d OFFSET %.1fpx", i, bestDist); + m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "pin %d OFFSET dx %.1f dy %.1f", i, absDx, absDy); } }