测量拟合的核心,是把离散的边缘点变成连续的几何图元——直线、圆、椭圆。这一步做得好不好,直接决定了最终尺寸的精度和稳定性。
为什么需要拟合
亚像素边缘提取出来的是一堆离散点,每个点都带有噪声。如果直接用两个点算距离,噪声会被放大;如果取多个点做平均,又无法处理“这些点本该在一条直线上”的几何约束。
拟合的作用是:用一条数学曲线去“穿过”这些点,让曲线尽可能贴近所有点,同时平滑掉噪声。拟合后的直线或圆,其参数(斜率、截距、圆心、半径)就是测量结果。
三种核心拟合
直线拟合:最常用,也是其他拟合的基础。给定一组边缘点,找一条直线使所有点到直线的距离平方和最小。这就是最小二乘法。
// OpenCV 直线拟合Matpoints=newMat(edgePoints.Count,1,MatType.CV_32FC2);// ... 填充点坐标 ...Cv2.FitLine(points,outvarline,DistanceTypes.L2,0,0.01,0.01);// line 包含方向向量和直线上一点圆拟合:给定一组边缘点,找圆心和半径。工业上测孔、测圆柱、测圆弧都靠它。
// Halcon 圆拟合(伪代码)fit_circle_contour_xld(Contour,'algebraic',-1,0,0,3,2,Row,Column,Radius,StartPhi,EndPhi,PointOrder)椭圆拟合:当圆被倾斜拍摄时,在图像上呈现为椭圆。椭圆拟合输出长轴、短轴、旋转角度,用于测量倾斜视角下的圆形物体。
拟合的关键:剔除“坏点”
坏点是拟合精度的头号杀手。边缘提取总会引入一些错误点——可能是噪声引起的,可能是附近有其他边缘干扰,也可能是物体表面有污点。如果把这些坏点也纳入拟合,直线会偏、圆会歪。
RANSAC 是工业上最常用的剔除策略:
- 随机选最少数量的点(直线选2个,圆选3个)拟合一个初始模型
- 计算所有点到这个模型的距离,距离小于阈值的算“内点”
- 统计内点数量,记录内点最多的模型
- 重复多次,选内点最多的模型作为最终结果
// RANSAC 直线拟合的简化逻辑intbestInlierCount=0;LinebestLine=null;for(inti=0;i<iterations;i++){varp1=points[random.Next(points.Count)];varp2=points[random.Next(points.Count)];varline=FitLineFromTwoPoints(p1,p2);intinliers=points.Count(p=>DistanceToLine(p,line)<threshold);if(inliers>bestInlierCount){bestInlierCount=inliers;bestLine=line;}}实战案例:E型卡簧尺寸检测
这个案例来自实际产线,完整展示了“匹配定位 → 亚像素边缘 → 拟合 → 测量”的链路。
检测目标:卡簧的内径、外径、开口宽度。
流程:
- 形状匹配定位:用
find_shape_model找到卡簧的位置和角度,建立跟随坐标系 - 亚像素边缘提取:在跟随坐标系下,沿径向射线用卡尺提取内外圆的边缘点
- 圆拟合:对内圆边缘点做 RANSAC 剔除坏点,然后最小二乘拟合圆,得到内径
- 直线拟合:对开口两侧的边缘点分别拟合直线,计算开口宽度
- 判定:将测量值与公差带比较,输出 OK/NG
精度提升的关键:拟合前先用 RANSAC 剔除偏离主趋势超过 2 个像素的点,再把剩余点做最小二乘。这一步把直径测量重复性从 ±0.05mm 提升到 ±0.01mm。
拟合精度的决定因素
边缘点的质量 > 拟合算法。如果边缘提取本身就偏了 0.5 个像素,再好的拟合也救不回来。边缘质量取决于:光源是否稳定、边缘是否清晰、亚像素算法是否合适。
点数要足够但不能太多。太少(如直线少于 5 个点)拟合不稳定;太多(如整个圆用 1000 个点)会把远处的坏点也拉进来。工业上通常取 20-50 个点做拟合。
拟合模型要匹配物理现实。孔是圆的,就拟合圆;如果孔被磨损成了椭圆,硬拟合圆会掩盖真实问题。有时候“拟合得不好”本身就是一种检测信号。
一句话总结
测量拟合的本质是用几何模型去逼近离散边缘点。直线拟合是基础,圆拟合是核心,RANSAC 是剔除坏点的保险。拟合精度首先取决于边缘质量,其次才是算法选择。工业测量的可靠性,来自“稳定成像 + 精准边缘 + 鲁棒拟合”的层层保障。