基于Emgu CV从Blob提取线条:未闭合矩形边缘拟合问题
问题:拟合未闭合矩形的边缘
处理后图像

需求描述
需要为图像中显示的大矩形内周拟合线条。目前遇到的问题是,由于轮廓在角落处未闭合,使用bounding rectangle方法时,矩形会贴合右下角突出的细线,导致尺寸计算错误。
重要条件:线条无需从矩形的角落开始或结束。需要获取左边缘的最右点、右边缘的最左点;对于上下边缘,需要获取上边缘的最低点和下边缘的最高点。
期望处理效果示意图

已尝试方案
CvInvoke.FindContours(workingImage, contours, m, Emgu.CV.CvEnum.RetrType.List, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); CvInvoke.ApproxPolyDP(contours[i], approx, precision * perimeter, true); CvInvoke.BoundingRectangle(contours[i]);
原本期望ApproxPolyDP能尝试闭合轮廓,但这并未解决问题。
疑问
- 在已完成图像处理的情况下,面对无尖锐角、边缘略有弧度且矩形形状未闭合的情况,应如何提取该形状的几何特征?
- 先为边缘拟合线条,再由这些线条构建矩形是否更合理?
- 若拟合线条是正确方案,如何确保线条绘制在形状内部?
- 是否有方法强制闭合该形状?
解决方案
1. 分离四条边缘并分别拟合直线
既然轮廓未闭合且有干扰,优先拆分点集单独拟合更可靠:
- 划分点集:把轮廓上的所有点按坐标聚类,比如按x坐标中位数分成左右两组,按y坐标中位数分成上下两组;也可以用K-means聚类直接分成4类,对应四条边。提前过滤异常点(比如右下角细线的点,坐标明显偏离主矩形范围)。
- 拟合直线:对每组点用
CvInvoke.FitLine()拟合最优直线,该函数支持无序点集,不需要轮廓闭合。 - 提取特征点:左边缘直线取x最大的点,右边缘取x最小的点,上边缘取y最大的点,下边缘取y最小的点,用这些点构建所需线段。
2. 确保线条在形状内部的方法
- 拟合直线后,计算轮廓点到直线的距离,判断大部分点位于直线的哪一侧,将直线向该侧偏移(偏移量取距离的均值或中位数)。
- 拟合前筛选点:比如左边缘只保留x偏小、y在主矩形y范围内的点,避免混入干扰点,从源头上保证拟合的直线贴近内侧。
3. 强制闭合形状的可选方案
- 用
CvInvoke.ConvexHull()生成凸包自动闭合,但需要先过滤右下角的干扰点,否则凸包会包含多余部分。 - 手动连接轮廓首尾点后再用
ApproxPolyDP拟合,但这种方法对带干扰的未闭合轮廓效果差,不如拆分边缘拟合实用。
内容的提问来源于stack exchange,提问作者CollC
相关产品推荐
相关产品推荐

