segment_contours_xld(Contours : ContoursSplit : Mode, SmoothCont, MaxLineDist1, MaxLineDist2 : )
segment_contours_xld将输入轮廓线分割为线段(如果Mode='lines'),
线段和圆弧(如果Mode='lines_circles'),
或者线段和椭圆圆弧(如果Mode='lines_ellipses')。
结果保存在ContoursSplit 。
输出轮廓是表示直线还是圆形或椭圆形弧,
可以通过全局轮廓属性'cont_approx'完成的(请参阅get_contour_global_attrib_xld)。
如果'cont_approx'=-1,则轮廓适合由线段逼近;
如果'cont_approx'=0,则由椭圆曲线逼近;
如果'cont_approx'=1,则由圆弧逼近。
segment_contours_xld首先用多边形逼近输入轮廓。
这样,轮廓在曲线区域被过度分割。
在此之后,如果可以用圆弧更好地逼近轮廓,
则将相邻线段分别用圆弧或椭圆圆弧代替。
如果SmoothCont设置为一个大于0的值,
则首先对输入轮廓进行平滑(请参阅smooth_contours_xld)。
这可能是必要的,可以防止非常短的段在多边形中逼近,
并实现一个更稳定圆形或椭圆形弧拟合,因为平滑抑制了轮廓上的异常值。
初始多边形逼近是使用最大距离为MaxLineDist1的Ramer算法(参见gen_polygons_xld)完成的。
然后,将圆形或椭圆形的弧放入相邻的线段中。
如果得到的圆弧到轮廓线的最大距离小于两个线段的最大距离,
则用圆弧代替这两个线段。
此过程将迭代,直到不再发生任何更改。
在此基础上,对轮廓线中仍然被线段近似的部分,
再次进行线段分割,采用最大距离MaxLineDist2的多边形近似,
并在可能的情况下,将新创建的线段合并为圆形或椭圆形圆弧。
显然,只有当MaxLineDist2 < MaxLineDist1时,才会更改输出。
这种两步方法比使用MaxLineDist2的单步方法更有效,
因为第一步生成的线段更少,因此圆或椭圆拟合的执行次数更少。
因此,可以更有效地找到可以用长弧近似的部分输入轮廓。
在第二步中,找到输入轮廓中可以近似为短弧的部分,
并对长弧的末端部分进行细化。
所得到的轮廓至少为3像素长,
且包含输入轮廓的至少6个连续点。
将所有长度小于3像素或轮廓点小于6的输入轮廓复制到输出轮廓上,不做任何修改。
例程
read_image (Image, 'pumpe')
*提取图像XLD轮廓
edges_sub_pix (Image, Edges, 'canny', 1.5, 15, 40)
*分割轮廓
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2)
count_obj (ContoursSplit, Number)
gen_empty_obj (Lines)
gen_empty_obj (Circles)
for I := 1 to Number by 1
select_obj (ContoursSplit, Contour, I)
*根据轮廓属性进行分类,分成适合拟合成线段和圆的轮廓
get_contour_global_attrib_xld (Contour, 'cont_approx', Type)
if (Type == -1)
concat_obj (Lines, Contour, Lines)
else
concat_obj (Circles, Contour, Circles)
endif
endfor
stop()
*轮廓拟合成线段和圆
fit_line_contour_xld (Lines, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
fit_circle_contour_xld (Circles, 'atukey', -1, 2, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
|