涉及函数
edges_sub_pix
寻找边缘
edges_sub_pix (Image, Edges, 'canny', 1, 10, 20)
后面三个参数,越小,找到的细节越多。这个是对应录波器为'canny'时。
'canny'滤波器用的最多。
segment_contours_xld
将连续的轮廓进行分段,按圆弧或者执行分段
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 3)
经过这个函数之后,就不会存在直线和圆弧的其他种类的线条。比如折线就不存在了!
折线会被打断成两条直线。
select_contours_xld
对轮廓的某个特征进行筛选:
select_contours_xld (ContoursSplit, SelectedContours, 'contour_length', 120, 300000, -0.5, 0.5)
union_adjacent_contours_xld
将相近的轮廓合并成一个轮廓。
union_adjacent_contours_xld (SelectedContours, UnionContours, 100, 1, 'attr_keep')
参数中的100表示只要距离相近100以内就连起来。
fit_circle_contour_xld
将轮廓拟合成圆弧
fit_circle_contour_xld (ObjectSelected, 'ahuber', -1, 2, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
前面的参数基本都使用默认即可,后面的: Row, Column, Radius, StartPhi, EndPhi, PointOrder,均为输出参数。
利用输出的 Row, Column, Radius,可以根据圆弧生成完整的圆轮廓:
gen_circle_contour_xld (ContCircle, row, column, radius, 0, rad(360), 'positive', 1.0)
circularity_xld
可获取轮廓的圆度:
circularity_xld(ObjectSelected, Circularity)
length_xld
可获取轮廓的长度
length_xld (ObjectSelected, Length)
get_contour_global_attrib_xld
get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib)
但是这个函数使用时要注意,所有的轮廓必须先 使用 segment_contours_xld 进行分段。
比如如果有个折线,调用 get_contour_global_attrib_xld 就会报错!Contour attribute not defined
这是因为折线不属于圆弧椭圆弧以及直线。
特别是使用了 union_adjacent_contours_xld 之后注意一定要 使用 segment_contours_xld 进行打断,然后才能使用 get_contour_global_attrib_xld。
结果展示
使用以上函数就能将圆识别到
思路
先通过edges_sub_pix 找到边缘轮廓,过滤掉一些直线以及短的。将剩下的圆弧轮廓进行联合(更长的圆形轮廓有助于拟合出更准确的圆)从联合后的轮廓中选出最长的,进行拟合圆:
dev_close_window()
dev_update_off ()
read_image (Image, 'D:/视觉图片资料/13.jpg')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
edges_sub_pix (Image, Edges, 'canny', 1, 10, 20)
*将连续的轮廓进行分段,按圆弧或者执行分段
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 3)
select_contours_xld (ContoursSplit, SelectedContours, 'contour_length', 120, 300000, -0.5, 0.5)
*合并较近的轮廓
union_adjacent_contours_xld (SelectedContours, UnionContours, 100, 1, 'attr_keep')
segment_contours_xld (UnionContours, ContoursSplit, 'lines_circles', 5, 4, 3)
count_obj (ContoursSplit, Number)
dev_display (Image)
dev_set_draw ('margin')
dev_set_color ('white')
dev_update_window ('off')
length := 0
select := 0
row:= 0
column:= 0
radius:= 0
gen_empty_obj (EmptyObject)
for I := 1 to Number by 1
select_obj (ContoursSplit, ObjectSelected, I)
get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib)
* 该值如果大于0,说明为圆弧。
if (Attrib > 0)
concat_obj (ObjectSelected,EmptyObject , EmptyObject)
fit_circle_contour_xld (ObjectSelected, 'ahuber', -1, 2, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
*circularity_xld(ObjectSelected, Circularity)
length_xld (ObjectSelected, Length)
if(Length > length)
length := Length
row:=Row
column:=Column
radius:=Radius
select := I
endif
endif
endfor
select_obj (ContoursSplit, ObjectSelected, select)
gen_circle_contour_xld (ContCircle, row, column, radius, 0, rad(360), 'positive', 1.0)
dev_display (ContCircle)
dev_set_colored (12)
dev_set_line_width (3)
dev_display (SelectedContours)