feat Pin添加dxdy日志

dev_lsy
liusiyang 3 weeks ago
parent 3fabada875
commit b7da6688ba

@ -2228,19 +2228,13 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
}
std::vector<bool> curUsed(nCur, false);
// 3、偏移阈值由基础参数 pin_x_offset / pin_y_offset (mm) 换算为像素
float offsetThX = 0.0f;
float offsetThY = 0.0f;
// 3、偏移阈值直接使用基础参数 pin_x_offset / pin_y_offset (mm),与换算为 mm 的偏移量直接比较
float offsetThX = 0.0f; // mm
float offsetThY = 0.0f; // mm
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;
}
offsetThX = m_pbaseCheckFunction->pinDet.pin_x_offset;
offsetThY = m_pbaseCheckFunction->pinDet.pin_y_offset;
}
// 上报缺失/偏移缺陷(缺陷类型可按需调整)
@ -2309,19 +2303,21 @@ int ImgCheckAnalysisy::Pin_Qx_Det(const cv::Mat &img)
curUsed[bestIdx] = true;
// 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)
// x 或 y 方向偏移超过配置阈值 -> 偏移;偏移量按成像精度换算为 mm (mm = px * 成像精度)
float dx_mm = (tplCenters[i].x - curCenters[bestIdx].x) * m_fImgage_Scale_X;
float dy_mm = (tplCenters[i].y - curCenters[bestIdx].y) * m_fImgage_Scale_Y;
float absDx = std::fabs(dx_mm);
float absDy = std::fabs(dy_mm);
bool bOffset = (absDx > offsetThX || absDy > offsetThY);
if (bOffset)
{
nOffset++;
char buf[64];
snprintf(buf, sizeof(buf), "offset dx %.1f dy %.1f", absDx, absDy);
snprintf(buf, sizeof(buf), "offset dx %.2f dy %.2f mm", absDx, absDy);
reportPinError(i, tplCenters[i], buf, CONFIG_QX_NAME_PIN_PianYi);
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "pin %d OFFSET dx %.1f dy %.1f", i, absDx, absDy);
}
// 每个pin脚都打印dx/dy(mm),方便调整 pin_x_offset / pin_y_offset 参数
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "pin %d %s dx %.2f dy %.2f mm", i, bOffset ? "OFFSET" : "OK", absDx, absDy);
}
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "tpl %d cur %d miss %d offset %d", nTpl, nCur, nMiss, nOffset);
@ -2639,8 +2635,8 @@ int ImgCheckAnalysisy::Pin_Direct_Match()
// 新方案(开关 PIN_USE_DIRECT_MATCH = 1): 不做模板对比, 只针对检测Pin分析
// 1) 方向扫描(0~180°, 步长1°): 取 "两排Pin沿法线投影组内方差之和" 最小的角度作为Pin排方向(对图像旋转不敏感),
// 再沿该法线投影, 在最大间隙处把Pin分成两排(两排插口; Pin不足4个则按一排处理);
// 2) 每排做最小二乘直线拟合(cv::fitLine): pin中心到直线(沿法线方向)距离超过 pin_y_offset(换算像素) 判 偏移;
// 3) 每排内沿排方向排序: 相邻两pin中心连线距离超过 pin_x_offset(换算像素) 判 两pin中间缺失一个pin。
// 2) 每排做最小二乘直线拟合(cv::fitLine): pin中心到直线(沿法线方向)距离按成像精度换算为 mm, 超过 pin_y_offset(mm) 判 偏移;
// 3) 每排内沿排方向排序: 相邻两pin中心连线距离按成像精度换算为 mm, 超过 pin_x_offset(mm) 判 两pin中间缺失一个pin。
int ImgCheckAnalysisy::Pin_Direct_Check()
{
// 计算轮廓中心点(外接矩形中心)
@ -2672,19 +2668,13 @@ int ImgCheckAnalysisy::Pin_Direct_Check()
return 0;
}
// 阈值(mm 参数换算为像素): pin_x_offset -> 相邻pin间距(缺失)阈值; pin_y_offset -> 到拟合直线距离(偏移)阈值; <=0 时不判该项
float offsetThX = 0.0f;
float offsetThY = 0.0f;
// 阈值直接使用 mm 参数(判据按 mm 比较): pin_x_offset -> 相邻pin间距(缺失)阈值; pin_y_offset -> 到拟合直线距离(偏移)阈值; <=0 时不判该项
float offsetThX = 0.0f; // mm
float offsetThY = 0.0f; // mm
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;
}
offsetThX = m_pbaseCheckFunction->pinDet.pin_x_offset;
offsetThY = m_pbaseCheckFunction->pinDet.pin_y_offset;
}
// 沿给定方向投影排序, 在最大间隙处切分成两排(order[0..splitK] 一排, order[splitK+1..] 另一排)
@ -2801,11 +2791,11 @@ int ImgCheckAnalysisy::Pin_Direct_Check()
rows.push_back(order);
}
m_pdetlog->AddCheckstr(PrintLevel_1, DET_LOG_LEVEL_3, "Pin Check",
"row dir %.1f deg rows %d th[gap %.1f line %.1f] px",
"row dir %.1f deg rows %d th[gap %.2f line %.2f] mm",
bestTheta * 180.0f / static_cast<float>(CV_PI),
static_cast<int>(rows.size()), offsetThX, offsetThY);
// 上报缺陷(roi/area 由调用处给出; grayDis 记录对应度量: 到直线距离 / 相邻间距, 单位像素)
// 上报缺陷(roi/area 由调用处给出; grayDis 记录对应度量: 到直线距离 / 相邻间距, 单位mm)
auto reportPinError = [&](const cv::Rect &roi, int area, double grayDis, int nconfig_qx_type, const std::string &detail)
{
QX_ERROR_INFO_ pinErr;
@ -2870,23 +2860,28 @@ int ImgCheckAnalysisy::Pin_Direct_Check()
}
m_pinFitLines.push_back(std::make_pair(lineP0 + lineDir * tMin, lineP0 + lineDir * tMax));
// 2、pin中心到直线(沿法线方向)距离超过 pin_y_offset -> 偏移
// 2、pin中心到直线(沿法线方向)距离超过 pin_y_offset -> 偏移;距离按成像精度换算为 mm (mm = px * 成像精度)
if (offsetThY > 0.0f)
{
for (int i = 0; i < nRow; i++)
{
float absDist = std::fabs((rowPts[i] - lineP0).dot(lineNor));
if (absDist > offsetThY)
// 垂直偏移向量(px)的分量分别换算为 mm 后求模
float distPx = (rowPts[i] - lineP0).dot(lineNor);
float dx_mm = lineNor.x * distPx * m_fImgage_Scale_X;
float dy_mm = lineNor.y * distPx * m_fImgage_Scale_Y;
float absDist = std::sqrt(dx_mm * dx_mm + dy_mm * dy_mm);
int idx = rowIdx[i];
bool bOffset = (absDist > offsetThY);
if (bOffset)
{
int idx = rowIdx[i];
nOffset++;
char buf[96];
snprintf(buf, sizeof(buf), "pin %d offset to row line %.1f px > %.1f px", idx, absDist, offsetThY);
snprintf(buf, sizeof(buf), "pin %d offset to row line %.2f mm > %.2f mm", idx, absDist, offsetThY);
reportPinError(curRects[idx], static_cast<int>(cv::contourArea(m_curPinContours[idx])),
absDist, CONFIG_QX_NAME_PIN_PianYi, buf);
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "row %d pin %d OFFSET %.1f px > %.1f px",
static_cast<int>(r), idx, absDist, offsetThY);
}
// 每个pin脚都打印到拟合直线的距离(mm),方便调整 pin_y_offset 参数
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "row %d pin %d %s line %.2f mm", static_cast<int>(r), idx, bOffset ? "OFFSET" : "OK", absDist);
}
}
@ -2905,11 +2900,16 @@ int ImgCheckAnalysisy::Pin_Direct_Check()
{
int ia = tOrder[i].second;
int ib = tOrder[i + 1].second;
float gap = static_cast<float>(cv::norm(rowPts[ib] - rowPts[ia]));
if (gap > offsetThX)
// 相邻pin中心连线距离(px)的分量分别换算为 mm 后求模
cv::Point2f dv = rowPts[ib] - rowPts[ia];
float dx_mm = dv.x * m_fImgage_Scale_X;
float dy_mm = dv.y * m_fImgage_Scale_Y;
float gap = std::sqrt(dx_mm * dx_mm + dy_mm * dy_mm);
int idxa = rowIdx[ia];
int idxb = rowIdx[ib];
bool bMiss = (gap > offsetThX);
if (bMiss)
{
int idxa = rowIdx[ia];
int idxb = rowIdx[ib];
cv::Point2f mid = (rowPts[ia] + rowPts[ib]) * 0.5f;
m_pinMissMarks.push_back(mid);
@ -2923,11 +2923,11 @@ int ImgCheckAnalysisy::Pin_Direct_Check()
static_cast<int>(cv::contourArea(m_curPinContours[idxb]))) / 2;
nMiss++;
char buf[96];
snprintf(buf, sizeof(buf), "miss between pin %d-%d gap %.1f px > %.1f px", idxa, idxb, gap, offsetThX);
snprintf(buf, sizeof(buf), "miss between pin %d-%d gap %.2f mm > %.2f mm", idxa, idxb, gap, offsetThX);
reportPinError(roiMiss, areaAvg, gap, CONFIG_QX_NAME_PIN_QueShi, buf);
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "row %d pin %d-%d MISS gap %.1f px > %.1f px",
static_cast<int>(r), idxa, idxb, gap, offsetThX);
}
// 每对相邻pin都打印间距(mm),方便调整 pin_x_offset 参数
m_pdetlog->AddCheckstr(PrintLevel_0, "Pin Check", "row %d pin %d-%d %s gap %.2f mm", static_cast<int>(r), idxa, idxb, bMiss ? "MISS" : "OK", gap);
}
}
}

Loading…
Cancel
Save