feat 临时补丁

dev_lsy
liusiyang 2 months ago
parent 6099c864ee
commit db455bd0cb

@ -0,0 +1,51 @@
#ifndef _ImgMmPatch_HPP_
#define _ImgMmPatch_HPP_
// ============================================================================
// 【临时补丁】产品长度方向(y) 像素 -> 物理毫米 的分段换算
//
// 背景:产品沿长度方向运动/扫描时速率不恒定(尾端有拉伸),像素↔mm 不是单一
// 比例,实测标定出 5 段,每段斜率不同。
//
// 分段表(分段点 = 像素,**以产品顶边为 0 点**;斜率为 mm/px):
// 0 ~ 10928 0.016869
// 10928 ~ 17002 0.016463 (6074px ↔ 100mm)
// 17002 ~ 23167 0.016220 (6165px ↔ 100mm)
// 23167 ~ 29549 0.015669 (6382px ↔ 100mm)
// >= 29549 0.014337
// 分段点处前后两段取值相同,函数连续,不会在分段点跳变。
//
// 共用方(必须共用同一张表,否则"产品高度"和"缺陷坐标"会各用一把尺子):
// 1) 缺陷 y 物理坐标:ImageResultJudge::BuildDefectImage()
// 2) 产品物理高度 :ImgCheckAnalysisy::CalProductSize()
//
// 注:正式方案建议把这张分段表放进配置(json),由标定数据下发;这里先硬编码。
// ============================================================================
inline float PixelYToMm(float fYPixel)
{
// 各段末端的累计物理长度(mm)
const float d1 = 10928 * 0.016869;
const float d2 = 6074 * 0.016463;
const float d3 = 6165 * 0.016220;
const float d4 = 6382 * 0.015669;
if (fYPixel < 10928.0f)
{
return fYPixel * 0.016869;
}
if (fYPixel < 17002.0f)
{
return (fYPixel - 10928.0f) * 0.016463 + d1;
}
if (fYPixel < 23167.0f)
{
return (fYPixel - 10928.0f - 6074.0f) * 0.016220 + d1 + d2;
}
if (fYPixel < 29549.0f)
{
return (fYPixel - 10928.0f - 6074.0f - 6165.0f) * 0.015669 + d1 + d2 + d3;
}
return (fYPixel - 10928.0f - 6074.0f - 6165.0f - 6382.0f) * 0.014337 + d1 + d2 + d3 + d4;
}
#endif

@ -1,5 +1,6 @@
#include "ImageResultJudge.h"
#include "ImgMmPatch.hpp"
ImageResultJudge::ImageResultJudge(/* args */)
{
@ -186,7 +187,9 @@ QXImageResult ImageResultJudge::BuildDefectImage(std::shared_ptr<ImageAllResult>
}
tem.x_mm = tem.x_pixel * m_fImgage_Scale_X;
tem.y_mm = tem.y_pixel * m_fImgage_Scale_Y;
// 【临时补丁】长度方向(y):产品运动速率不恒定(尾端有拉伸),按分段像素进度换算像素->mm
// 分段表见 ImgMmPatch.hpp,与产品物理高度(ImgCheckAnalysisy::CalProductSize)共用
tem.y_mm = PixelYToMm(tem.y_pixel);
tem.CutImgroi = roi_det;
tem.CutImgroi.x -= CutRoi.x;

@ -8,6 +8,7 @@
*/
#include "ImgCheckAnalysisy.hpp"
#include "CheckUtil.hpp"
#include "ImgMmPatch.hpp"
#include "Define.h"
#include <omp.h>
#include "AICommonDefine.h"
@ -2819,6 +2820,7 @@ int ImgCheckAnalysisy::AI_Edge(const cv::Mat &img, cv::Rect &cutRoi)
int ImgCheckAnalysisy::CalProductSize()
{
float fw, fh;
float fhPixel = 0.f; // 产品沿长度方向(y)的像素高度,供长度方向分段补丁换算用
if (m_bRotCurRoiValid)
{
// 产品存在旋转角:用旋转矩形四个顶点的实际边长换算物理尺寸
@ -2829,21 +2831,31 @@ int ImgCheckAnalysisy::CalProductSize()
double dy = (a.y - b.y) * m_fImgage_Scale_Y;
return std::sqrt(dx * dx + dy * dy);
};
// 纯像素边长(不带成像精度),供长度方向的分段补丁使用
auto edgeLenPixel = [&](const cv::Point2f &a, const cv::Point2f &b) -> double {
double dx = a.x - b.x;
double dy = a.y - b.y;
return std::sqrt(dx * dx + dy * dy);
};
fw = (float)((edgeLenPhys(v[0], v[1]) + edgeLenPhys(v[2], v[3])) * 0.5); // 上边+下边平均
fh = (float)((edgeLenPhys(v[0], v[2]) + edgeLenPhys(v[1], v[3])) * 0.5); // 左边+右边平均
fhPixel = (float)((edgeLenPixel(v[0], v[2]) + edgeLenPixel(v[1], v[3])) * 0.5); // 左边+右边平均(像素)
}
else
{
fw = m_CutRoi.width * m_fImgage_Scale_X;
fh = m_CutRoi.height * m_fImgage_Scale_Y;
fhPixel = (float)m_CutRoi.height;
}
// 【临时补丁】长度方向(上下边)产品运动速率不恒定,按分段像素进度换算像素->mm;
// 与缺陷 y 坐标(ImageResultJudge::BuildDefectImage)共用 ImgMmPatch.hpp 里的同一张分段表。
// 宽度不做补丁,仍用成像精度换算。
fh = PixelYToMm(fhPixel);
fw = std::ceil(fw * 10) / 10;
fh = std::ceil(fh * 10) / 10;
m_CheckResult_shareP->productWidht_mm = fw;
m_CheckResult_shareP->productHeight_mm = fh;
m_pdetlog->AddCheckstr(PrintLevel_1, "Det ROI", " [x%d, y%d, w %d,h %d] (piexl) -> [w %f h %f](mm),scale %f %f",
m_CutRoi.x, m_CutRoi.y, m_CutRoi.width, m_CutRoi.height, fw, fh, m_fImgage_Scale_X, m_fImgage_Scale_Y);
m_pdetlog->AddCheckstr(PrintLevel_1, "Det ROI", " [x%d, y%d, w %d,h %d] (piexl) -> [w %f h %f](mm),scale %f %f, hPixel %f",
m_CutRoi.x, m_CutRoi.y, m_CutRoi.width, m_CutRoi.height, fw, fh, m_fImgage_Scale_X, m_fImgage_Scale_Y, fhPixel);
// 打印产品旋转矩形的四角坐标(原图坐标系),便于核对尺寸换算与后续坐标映射
if (m_bRotCurRoiValid)

Loading…
Cancel
Save