|
|
|
@ -12,6 +12,7 @@
|
|
|
|
#include <omp.h>
|
|
|
|
#include <omp.h>
|
|
|
|
#include <map>
|
|
|
|
#include <map>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include <cctype>
|
|
|
|
#include "AICommonDefine.h"
|
|
|
|
#include "AICommonDefine.h"
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <fstream>
|
|
|
|
#include <fstream>
|
|
|
|
@ -805,65 +806,69 @@ int ImgCheckAnalysisy::CheckRun()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*投影对齐模板*/
|
|
|
|
/*投影对齐模板*/
|
|
|
|
#if PIN_USE_DIRECT_MATCH
|
|
|
|
// Pin 检测方案由参数 Det_Method 运行时选择(替代原 PIN_USE_DIRECT_MATCH 编译宏)
|
|
|
|
// 新方案(开关 PIN_USE_DIRECT_MATCH = 1): 不做仿射变换, 检测图直接按当前外定位结果裁剪;
|
|
|
|
if (IsDirectPinMethod())
|
|
|
|
// Pin分析在 Pin_Qx_Det -> Pin_Direct_Check 中完成(只分析检测Pin, 不做模板对比)
|
|
|
|
{
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "Align mode: Direct Pin Check (no affine)");
|
|
|
|
// 新方案(Det_Method == "line_fitting"): 不做仿射变换, 检测图直接按当前外定位结果裁剪;
|
|
|
|
{
|
|
|
|
// Pin分析在 Pin_Qx_Det -> Pin_Direct_Check 中完成(只分析检测Pin, 不做模板对比)
|
|
|
|
cv::Rect curOuterBound = m_outer_rroi.boundingRect();
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect", "Align mode: Direct Pin Check (no affine)");
|
|
|
|
cv::Rect curImgBound(0, 0, m_CheckResult_shareP->in_shareImage->img.cols,
|
|
|
|
{
|
|
|
|
m_CheckResult_shareP->in_shareImage->img.rows);
|
|
|
|
cv::Rect curOuterBound = m_outer_rroi.boundingRect();
|
|
|
|
curOuterBound &= curImgBound;
|
|
|
|
cv::Rect curImgBound(0, 0, m_CheckResult_shareP->in_shareImage->img.cols,
|
|
|
|
if (curOuterBound.width <= 0 || curOuterBound.height <= 0)
|
|
|
|
m_CheckResult_shareP->in_shareImage->img.rows);
|
|
|
|
{
|
|
|
|
curOuterBound &= curImgBound;
|
|
|
|
cv::Rect rawBound = m_outer_rroi.boundingRect();
|
|
|
|
if (curOuterBound.width <= 0 || curOuterBound.height <= 0)
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "Direct Pin Match: current outer roi invalid [%d %d %d %d]",
|
|
|
|
{
|
|
|
|
rawBound.x, rawBound.y, rawBound.width, rawBound.height);
|
|
|
|
cv::Rect rawBound = m_outer_rroi.boundingRect();
|
|
|
|
m_nErrorCode = CHECK_ERROR_Config_cutRoi;
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "Direct Pin Match: current outer roi invalid [%d %d %d %d]",
|
|
|
|
m_nCheckResultErrorCode = m_nErrorCode;
|
|
|
|
rawBound.x, rawBound.y, rawBound.width, rawBound.height);
|
|
|
|
return m_nErrorCode;
|
|
|
|
m_nErrorCode = CHECK_ERROR_Config_cutRoi;
|
|
|
|
|
|
|
|
m_nCheckResultErrorCode = m_nErrorCode;
|
|
|
|
|
|
|
|
return m_nErrorCode;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
m_outer_roi = curOuterBound;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_outer_roi = curOuterBound;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
// 不对原图做 warpAffine, 只计算矩阵, 并把模板 Pin 轮廓反变换到当前图坐标系。
|
|
|
|
|
|
|
|
bool bUseInnerAlign = (m_tplInnerRect.size.width > 0 && m_tplInnerRect.size.height > 0 &&
|
|
|
|
|
|
|
|
m_inner_rroi.size.width > 0 && m_inner_rroi.size.height > 0);
|
|
|
|
|
|
|
|
if (bUseInnerAlign)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect",
|
|
|
|
|
|
|
|
"Affine align basis: Inner(inner_rroi -> tplInnerRect), template pins warp only, image NOT warped");
|
|
|
|
|
|
|
|
CalAffineMats(m_tplInnerRect, m_inner_rroi);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect",
|
|
|
|
// 旧方案(Det_Method == "BTB_Marix" 或未配置): 不对原图做 warpAffine, 只计算矩阵, 并把模板 Pin 轮廓反变换到当前图坐标系。
|
|
|
|
"Affine align basis: Outer(outer_rroi -> tplOuterRect), template pins warp only, image NOT warped");
|
|
|
|
bool bUseInnerAlign = (m_tplInnerRect.size.width > 0 && m_tplInnerRect.size.height > 0 &&
|
|
|
|
CalAffineMats(m_tplOuterRect, m_outer_rroi);
|
|
|
|
m_inner_rroi.size.width > 0 && m_inner_rroi.size.height > 0);
|
|
|
|
}
|
|
|
|
if (bUseInnerAlign)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect",
|
|
|
|
|
|
|
|
"Affine align basis: Inner(inner_rroi -> tplInnerRect), template pins warp only, image NOT warped");
|
|
|
|
|
|
|
|
CalAffineMats(m_tplInnerRect, m_inner_rroi);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "2.1、pre detect",
|
|
|
|
|
|
|
|
"Affine align basis: Outer(outer_rroi -> tplOuterRect), template pins warp only, image NOT warped");
|
|
|
|
|
|
|
|
CalAffineMats(m_tplOuterRect, m_outer_rroi);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 后续所有检测/裁剪都在当前图坐标系: 裁剪框取当前外定位的包围框(原图不 warp)
|
|
|
|
// 后续所有检测/裁剪都在当前图坐标系: 裁剪框取当前外定位的包围框(原图不 warp)
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::Rect curOuterBound = m_outer_rroi.boundingRect();
|
|
|
|
|
|
|
|
cv::Rect curImgBound(0, 0, m_CheckResult_shareP->in_shareImage->img.cols,
|
|
|
|
|
|
|
|
m_CheckResult_shareP->in_shareImage->img.rows);
|
|
|
|
|
|
|
|
m_outer_roi = curOuterBound & curImgBound;
|
|
|
|
|
|
|
|
if (m_outer_roi.width <= 0 || m_outer_roi.height <= 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "Affine mode: current outer roi invalid [%d %d %d %d]",
|
|
|
|
cv::Rect curOuterBound = m_outer_rroi.boundingRect();
|
|
|
|
curOuterBound.x, curOuterBound.y, curOuterBound.width, curOuterBound.height);
|
|
|
|
cv::Rect curImgBound(0, 0, m_CheckResult_shareP->in_shareImage->img.cols,
|
|
|
|
m_nErrorCode = CHECK_ERROR_Config_cutRoi;
|
|
|
|
m_CheckResult_shareP->in_shareImage->img.rows);
|
|
|
|
m_nCheckResultErrorCode = m_nErrorCode;
|
|
|
|
m_outer_roi = curOuterBound & curImgBound;
|
|
|
|
return m_nErrorCode;
|
|
|
|
if (m_outer_roi.width <= 0 || m_outer_roi.height <= 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "Error", "Affine mode: current outer roi invalid [%d %d %d %d]",
|
|
|
|
|
|
|
|
curOuterBound.x, curOuterBound.y, curOuterBound.width, curOuterBound.height);
|
|
|
|
|
|
|
|
m_nErrorCode = CHECK_ERROR_Config_cutRoi;
|
|
|
|
|
|
|
|
m_nCheckResultErrorCode = m_nErrorCode;
|
|
|
|
|
|
|
|
return m_nErrorCode;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 模板 Pin(pinImg 坐标) -> 模板图坐标 -> 当前图坐标 -> detImg 坐标
|
|
|
|
// 模板 Pin(pinImg 坐标) -> 模板图坐标 -> 当前图坐标 -> detImg 坐标
|
|
|
|
TransformTplPinContoursToCur();
|
|
|
|
TransformTplPinContoursToCur();
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "2.1、pre detect",
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "2.1、pre detect",
|
|
|
|
"tpl pin contours -> current frame: %ld (affineValid %d)",
|
|
|
|
"tpl pin contours -> current frame: %ld (affineValid %d)",
|
|
|
|
static_cast<long>(m_tplPinContoursCur.size()), static_cast<int>(m_bAffineValid));
|
|
|
|
static_cast<long>(m_tplPinContoursCur.size()), static_cast<int>(m_bAffineValid));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
m_Crop_Roi_paramImg = m_outer_roi;
|
|
|
|
m_Crop_Roi_paramImg = m_outer_roi;
|
|
|
|
m_pImageAllResult->pDetResult->CutRoi = m_outer_roi;
|
|
|
|
m_pImageAllResult->pDetResult->CutRoi = m_outer_roi;
|
|
|
|
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
|
|
|
|
m_pImageAllResult->pDetResult->Param_CropRoi = m_Crop_Roi_paramImg;
|
|
|
|
@ -2127,27 +2132,28 @@ int ImgCheckAnalysisy::DrawResult_Step_1()
|
|
|
|
float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows;
|
|
|
|
float fs_resize_y = m_pImageAllResult->resultImg.rows * 1.0f / m_pImageAllResult->detImg.rows;
|
|
|
|
|
|
|
|
|
|
|
|
// 绘制模板 pin 轮廓(绿色)与当前 pin 轮廓(红色)
|
|
|
|
// 绘制模板 pin 轮廓(绿色)与当前 pin 轮廓(红色)
|
|
|
|
#if PIN_USE_DIRECT_MATCH
|
|
|
|
// Pin 绘制内容按当前检测方案选择: 新方案绘制拟合直线/缺失标记, 旧方案绘制反变换后的模板Pin
|
|
|
|
// 新方案: 模板pin已配准到当前检测图坐标系
|
|
|
|
std::vector<std::vector<cv::Point>> directDrawPinContours;
|
|
|
|
// 新方案: 不做模板对比; 将两排Pin拟合直线段与缺失标记组织成 2点"轮廓", 复用下方循环缩放绘制(绿色)
|
|
|
|
const std::vector<std::vector<cv::Point>> *pTplDrawPinContours = &m_tplPinContoursCur;
|
|
|
|
std::vector<std::vector<cv::Point>> tplDrawPinContours;
|
|
|
|
if (IsDirectPinMethod())
|
|
|
|
for (const auto &seg : m_pinFitLines)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
tplDrawPinContours.push_back({cv::Point(cvRound(seg.first.x), cvRound(seg.first.y)),
|
|
|
|
|
|
|
|
cv::Point(cvRound(seg.second.x), cvRound(seg.second.y))});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &mark : m_pinMissMarks)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 缺失位置: 十字标记(两条短线)
|
|
|
|
// 新方案: 不做模板对比; 将两排Pin拟合直线段与缺失标记组织成 2点"轮廓", 复用下方循环缩放绘制(绿色)
|
|
|
|
tplDrawPinContours.push_back({cv::Point(cvRound(mark.x - 6.0f), cvRound(mark.y)),
|
|
|
|
for (const auto &seg : m_pinFitLines)
|
|
|
|
cv::Point(cvRound(mark.x + 6.0f), cvRound(mark.y))});
|
|
|
|
{
|
|
|
|
tplDrawPinContours.push_back({cv::Point(cvRound(mark.x), cvRound(mark.y - 6.0f)),
|
|
|
|
directDrawPinContours.push_back({cv::Point(cvRound(seg.first.x), cvRound(seg.first.y)),
|
|
|
|
cv::Point(cvRound(mark.x), cvRound(mark.y + 6.0f))});
|
|
|
|
cv::Point(cvRound(seg.second.x), cvRound(seg.second.y))});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &mark : m_pinMissMarks)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 缺失位置: 十字标记(两条短线)
|
|
|
|
|
|
|
|
directDrawPinContours.push_back({cv::Point(cvRound(mark.x - 6.0f), cvRound(mark.y)),
|
|
|
|
|
|
|
|
cv::Point(cvRound(mark.x + 6.0f), cvRound(mark.y))});
|
|
|
|
|
|
|
|
directDrawPinContours.push_back({cv::Point(cvRound(mark.x), cvRound(mark.y - 6.0f)),
|
|
|
|
|
|
|
|
cv::Point(cvRound(mark.x), cvRound(mark.y + 6.0f))});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pTplDrawPinContours = &directDrawPinContours;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
for (const auto &contour : *pTplDrawPinContours)
|
|
|
|
const std::vector<std::vector<cv::Point>> &tplDrawPinContours = m_tplPinContoursCur;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (const auto &contour : tplDrawPinContours)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::vector<cv::Point> draw_pts;
|
|
|
|
std::vector<cv::Point> draw_pts;
|
|
|
|
draw_pts.reserve(contour.size());
|
|
|
|
draw_pts.reserve(contour.size());
|
|
|
|
@ -2240,6 +2246,31 @@ int ImgCheckAnalysisy::UpdateImgageScale()
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 当前 Pin 检测方案是否为"直接分析"(新方案): 由参数 pinDet.Det_Method 在运行时决定
|
|
|
|
|
|
|
|
// "line_fitting" -> 新方案(不做模板对比); 其它/未配置 -> 旧方案(模板对比)
|
|
|
|
|
|
|
|
bool ImgCheckAnalysisy::IsDirectPinMethod() const
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (m_pbaseCheckFunction == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string method = m_pbaseCheckFunction->pinDet.Det_Method;
|
|
|
|
|
|
|
|
// 去掉首尾空白并转小写, 兼容大小写/带空格的配置值
|
|
|
|
|
|
|
|
size_t begin = method.find_first_not_of(" \t\r\n");
|
|
|
|
|
|
|
|
if (begin == std::string::npos)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t end = method.find_last_not_of(" \t\r\n");
|
|
|
|
|
|
|
|
method = method.substr(begin, end - begin + 1);
|
|
|
|
|
|
|
|
std::transform(method.begin(), method.end(), method.begin(),
|
|
|
|
|
|
|
|
[](unsigned char c)
|
|
|
|
|
|
|
|
{ return static_cast<char>(std::tolower(c)); });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (method == "line_fitting");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
|
|
|
|
int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
@ -2278,10 +2309,12 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
|
|
|
|
m_curPinContours.push_back(mapped);
|
|
|
|
m_curPinContours.push_back(mapped);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if PIN_USE_DIRECT_MATCH
|
|
|
|
if (IsDirectPinMethod())
|
|
|
|
// 新方案: 不做模板对比, 只分析检测Pin(自动分两排 -> 逐排拟合直线判偏移 + 相邻间距判缺失)
|
|
|
|
{
|
|
|
|
Pin_Direct_Check();
|
|
|
|
// 新方案: 不做模板对比, 只分析检测Pin(自动分两排 -> 逐排拟合直线判偏移 + 相邻间距判缺失)
|
|
|
|
#else
|
|
|
|
Pin_Direct_Check();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
// 根据模板Pin和当前Pin轮廓进行对比,判断当前有无缺失和偏移
|
|
|
|
// 根据模板Pin和当前Pin轮廓进行对比,判断当前有无缺失和偏移
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 计算轮廓中心点(外接矩形中心)
|
|
|
|
// 计算轮廓中心点(外接矩形中心)
|
|
|
|
@ -2533,8 +2566,7 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "tpl %d cur %d miss %d offset %d", nTpl, nCur, nMiss, nOffset);
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "tpl %d cur %d miss %d offset %d", nTpl, nCur, nMiss, nOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_Edge_DetConfig.bSaveResultImg)
|
|
|
|
if (m_Edge_DetConfig.bSaveResultImg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// 画布优先用原图裁剪区(保持原图通道),ReJson 或异常时退回检测图
|
|
|
|
// 画布优先用原图裁剪区(保持原图通道),ReJson 或异常时退回检测图
|
|
|
|
@ -2554,29 +2586,31 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
|
|
|
|
showimg = img.clone();
|
|
|
|
showimg = img.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cv::drawContours(showimg, m_curPinContours, -1, CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 0, 255)), 1);
|
|
|
|
cv::drawContours(showimg, m_curPinContours, -1, CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 0, 255)), 1);
|
|
|
|
#if PIN_USE_DIRECT_MATCH
|
|
|
|
if (IsDirectPinMethod())
|
|
|
|
// 新方案: 绘制两排Pin的拟合直线(绿); 缺失位置以黄色十字标记
|
|
|
|
|
|
|
|
for (const auto &seg : m_pinFitLines)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cv::line(showimg, cv::Point(cvRound(seg.first.x), cvRound(seg.first.y)),
|
|
|
|
// 新方案: 绘制两排Pin的拟合直线(绿); 缺失位置以黄色十字标记
|
|
|
|
cv::Point(cvRound(seg.second.x), cvRound(seg.second.y)),
|
|
|
|
for (const auto &seg : m_pinFitLines)
|
|
|
|
CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 255, 0)), 1);
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::line(showimg, cv::Point(cvRound(seg.first.x), cvRound(seg.first.y)),
|
|
|
|
|
|
|
|
cv::Point(cvRound(seg.second.x), cvRound(seg.second.y)),
|
|
|
|
|
|
|
|
CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 255, 0)), 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto &mark : m_pinMissMarks)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cv::drawMarker(showimg, cv::Point(cvRound(mark.x), cvRound(mark.y)),
|
|
|
|
|
|
|
|
CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 255, 255)), cv::MARKER_CROSS, 16, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const auto &mark : m_pinMissMarks)
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
cv::drawMarker(showimg, cv::Point(cvRound(mark.x), cvRound(mark.y)),
|
|
|
|
cv::drawContours(showimg, m_tplPinContoursCur, -1, CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 255, 0)), 1);
|
|
|
|
CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 255, 255)), cv::MARKER_CROSS, 16, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
|
|
|
cv::drawContours(showimg, m_tplPinContoursCur, -1, CheckUtil::GetDrawColor(showimg, cv::Scalar(0, 255, 0)), 1);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
imwrite("pin_contours.png", showimg);
|
|
|
|
imwrite("pin_contours.png", showimg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if PIN_USE_DIRECT_MATCH
|
|
|
|
|
|
|
|
#if 0 // ----- 旧配准匹配方案(Pin_Direct_Match)已停用, 仅保留代码参考; 如需启用需恢复 m_tplPinContoursCur 成员 -----
|
|
|
|
#if 0 // ----- 旧配准匹配方案(Pin_Direct_Match)已停用, 仅保留代码参考; 如需启用需恢复 m_tplPinContoursCur 成员 -----
|
|
|
|
// 新方案(开关 PIN_USE_DIRECT_MATCH = 1): 不做仿射变换, 直接对模板Pin与检测Pin做配准后对比
|
|
|
|
// 新方案(开关 PIN_USE_DIRECT_MATCH = 1): 不做仿射变换, 直接对模板Pin与检测Pin做配准后对比
|
|
|
|
// 输入: m_tplPinContours(模板裁剪坐标系) / m_curPinContours(当前检测图坐标系)
|
|
|
|
// 输入: m_tplPinContours(模板裁剪坐标系) / m_curPinContours(当前检测图坐标系)
|
|
|
|
@ -2842,7 +2876,7 @@ int ImgCheckAnalysisy::Pin_Direct_Match()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// 新方案(开关 PIN_USE_DIRECT_MATCH = 1): 不做模板对比, 只针对检测Pin分析
|
|
|
|
// 新方案(Det_Method == "line_fitting"): 不做模板对比, 只针对检测Pin分析
|
|
|
|
// 1) 方向扫描(0~180°, 步长1°): 取 "两排Pin沿法线投影组内方差之和" 最小的角度作为Pin排方向(对图像旋转不敏感),
|
|
|
|
// 1) 方向扫描(0~180°, 步长1°): 取 "两排Pin沿法线投影组内方差之和" 最小的角度作为Pin排方向(对图像旋转不敏感),
|
|
|
|
// 再沿该法线投影, 在最大间隙处把Pin分成两排(两排插口; Pin不足4个则按一排处理);
|
|
|
|
// 再沿该法线投影, 在最大间隙处把Pin分成两排(两排插口; Pin不足4个则按一排处理);
|
|
|
|
// 2) 每排做最小二乘直线拟合(cv::fitLine): pin中心到直线(沿法线方向)距离按成像精度换算为 mm, 超过 pin_y_offset(mm) 判 偏移;
|
|
|
|
// 2) 每排做最小二乘直线拟合(cv::fitLine): pin中心到直线(沿法线方向)距离按成像精度换算为 mm, 超过 pin_y_offset(mm) 判 偏移;
|
|
|
|
@ -3147,7 +3181,6 @@ int ImgCheckAnalysisy::Pin_Direct_Check()
|
|
|
|
nCur, static_cast<int>(rows.size()), nMiss, nOffset);
|
|
|
|
nCur, static_cast<int>(rows.size()), nMiss, nOffset);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // PIN_USE_DIRECT_MATCH
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取指定 残点(blob) 是由哪个(哪些)检测模型检出的
|
|
|
|
// 获取指定 残点(blob) 是由哪个(哪些)检测模型检出的
|
|
|
|
// 做法:对各模型自己输出的全图 mask,在 blob 的 roi 内统计非零像素;
|
|
|
|
// 做法:对各模型自己输出的全图 mask,在 blob 的 roi 内统计非零像素;
|
|
|
|
|