Halcon 轮廓处理详解
Halcon 轮廓处理详解
Halcon是一款功能强大的机器视觉软件,其亚像素级的轮廓提取功能尤其出色。通过Halcon,可以将轮廓进一步分割成直线或圆弧,并提取如角度、中心或半径等参数进行深入分析。本文将详细介绍Halcon中轮廓处理的基本概念、扩展功能以及具体的操作步骤。
1 基本概念
1.1 提取轮廓XLD
在使用Halcon进行轮廓处理时,首先需要从图像中提取轮廓。这一步通常需要结合感兴趣区域(ROI)来完成,通过设置合适的ROI可以更准确地找到目标轮廓。提取轮廓时还需要充分考虑ROI的大小,以确保提取的准确性。
1.2 拟合处理
获取轮廓后,可以使用拟合算子来确定轮廓的几何参数,例如直线的端点坐标或圆的圆心和半径。为了获得最佳拟合效果,提取的目标轮廓应该尽可能接近于直线、矩形、圆形或椭圆。
1.3 特征提取
无论是原始轮廓还是经过处理的轮廓,都可以用来提取对象的特征。对于线性对象,可以提取其曲率等特征;对于封闭轮廓,则可以计算其重心。
2 扩展概念
2.1 创建轮廓XLD
创建轮廓是轮廓处理的第一步。可以通过多种算子来实现这一目标:
- 使用
edges_sub_pix
、edges_color_sub_pix
或zero_crossing_sub_pix
算子进行边缘轮廓提取。 - 使用
lines_gauss
、lines_facet
或lines_color
算子提取线条。 - 对于亚像素级的blob分析,可以使用
threshold_sub_pix
算子。 - 如果需要更高的像素精度,可以使用
sobel_amp
或edges_image
等边缘过滤器,或者使用bandpass_image
进行线性滤波。
创建轮廓后,可以使用gen_contours_skeleton_xld
算子将其绘制出来。此外,轮廓也可以从不同的数据源合成,如CAD数据、用户交互或测量数据,使用gen_contour_polygon_xld
和gen_contour_polygon_rounded_xld
算子将其转换为XLD轮廓。最后,可以使用draw_xld
和draw_xld_mode
算子进行交互式绘制,或将区域边界转换为轮廓。
2.2 处理轮廓XLD
轮廓处理的一个关键步骤是分割轮廓。可以使用segment_contours_xld
算子将轮廓分割成多个部分,然后根据需要提取直线、圆、椭圆等形状。使用select_obj
算子可以选择特定的轮廓段,并将其传递给拟合算子。可以通过cont_approx
算子查询轮廓是否包含直线、圆或椭圆,使用get_contour_global_attrib_xld
算子查询全局属性。
如果只需要提取线段,可以使用gen_ploygons_xld
和split_contours_xld
算子的组合。与segment_contours_xld
不同,gen_ploygons_xld
生成的是XLD多边形轮廓,它将段分割为平行线。
在处理轮廓时,剔除不相关的轮廓是一个重要步骤。可以使用select_shape_xld
算子,它提供了30多种形状特征,通过指定所需的最小值和最大值,可以灵活地提取轮廓。另一种方法是使用select_contours_xld
算子,它提供了一种线性结构的轮廓选择方式。此外,还可以使用select_xld_point
算子与鼠标函数结合,以交互方式选择轮廓。
2.3 拟合处理
从轮廓中分割出直线、矩形、圆弧或椭圆弧时,可以通过调用相应的算子来确定参数,例如直线端点的坐标或圆的圆心和半径。Halcon的拟合算法非常先进,能够获得可靠的参数。
2.4 特征提取
从原始轮廓或提取轮廓都能够确定零件特征。其中,一些轮科视为线性对象,另一些轮廓视为零件的外部对象。重心表示封闭轮廓,曲率表示线性轮廓特征。
2.5 示例
该例子,实现了轮廓提取,实现如何将短轮廓处理为反应真实情况的轮廓。
2.6 处理和转换轮廓XLD
要访问原始轮廓中的信息或将其转换为另一种数据类型,可以使用get_contour_xld
算子获取控制点的坐标,它以浮点数值元组的形式返回轮廓上所有点的行、列坐标。如果需要遍历筛选每个轮廓,可以使用select_obj
算子。
要将轮廓转换为区域,可以使用gen_region_contour_xld
算子。paint_xld
算子可以将重叠的轮廓绘制到图像中。提取轮廓的边缘和先等可返回XLD轮廓,也返回属性。属性是数值,他们与每个控制点相关联(称为轮廓属性)。算子get_contour_attrib_xld
和get_contour_global_attrib_xld
可以通过指定属性名称来访问这些值。
2.7 可视化结果
将处理结果先显示出来。
2.8 程序示例
下面是一个完整的示例程序,展示了如何使用Halcon进行轮廓检测、拟合和可视化:
* 通过拟合直线或圆检测零件
dev_close_window()
dev_update_window('off')
* step:读取图像
read_image(Image,'D:/Halcon_Study/LineCircle.bmp')
get_image_size(Image,Width,Height)
dev_open_window_fit_image(Image,0,0,Width,Height,WindowHandle)
set_display_font(WindowHandle,16, 'mono', 'true', 'false')
dev_set_draw('margin')
dev_set_line_width(3)
dev_display(Image)
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* step:创建轮廓
edges_sub_pix(Image,Edges,'lanser2',0.5,40,90)
dev_display(Edges)
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* step:轮廓处理
segment_contours_xld(Edges,ContoursSplit,'lines_circles',6,4,4)
sort_contours_xld(ContoursSplit,SortedContours,'upper_left','true','column')
dev_clear_window()
dev_set_colored(12)
dev_display(SortedContours)
disp_continue_message(WindowHandle, 'black', 'true')
stop()
* step:拟合处理
ROI:=[115,225,395,535]
dev_open_window(0,round(Width/2),Width,Height,'black',WindowHandleZoom)
dev_set_part(round([0]),round(ROI[1]),round(ROI[2]),round(ROI[3]))
set_display_font(WindowHandleZoom,16, 'mono', 'true', 'false')
count_obj(SortedContours,NumSegments)
dev_display(Image)
NumCircles:=0
NumLines:=0
for i:=1 to NumSegments by 1
select_obj(SortedContours,SingleSegment,i)
get_contour_global_attrib_xld(SingleSegment,'cont_approx',Attrib)
if(Attrib==1)
NumCircles:=NumCircles+1
fit_circle_contour_xld(SingleSegment,'atukey',-1,2,0,5,2,Row,Column,Radius,StartPhi,EndPhi,PointOrder)
gen_ellipse_contour_xld(ContEllipse,Row,Column,0,Radius,Radius,0,rad(360),'positive',1.0)
dev_set_color('white')
dev_display(ContEllipse)
set_tposition(WindowHandleZoom,Row-Radius-10,Column)
write_string(WindowHandleZoom,'C'+NumCircles)
ResultText:='C'+NumCircles+' :radius='+Radius
else
NumLines:=NumLines+1
fit_line_contour_xld(SingleSegment,'tukey',-1,0,5,2,RowBegin,ColBegin,RowEnd,ColEnd,Nr,Nc,Dist)
gen_contour_polygon_xld(Line,[RowBegin,RowEnd],[ColBegin,ColEnd])
dev_set_color('yellow')
distance_pp(RowBegin,ColBegin,RowEnd,ColEnd,Length)
set_tposition(WindowHandleZoom,(RowBegin+RowEnd)-Nr*10,(ColBegin+ColEnd))
write_string(WindowHandleZoom,'L'+NumLines)
ResultText:='L'+NumLines+':length='+Length
endif
set_tposition(WindowHandleZoom,275+i*10,230)
write_string(WindowHandleZoom,ResultText)
endfor
disp_continue_message(WindowHandle,'black', 'true')
stop()
dev_set_window(WindowHandleZoom)
dev_close_window()
dev_clear_window()
这个示例程序展示了如何读取图像、创建轮廓、处理轮廓以及进行拟合处理。通过这些步骤,可以实现对零件的自动检测和特征提取。