Halcon 轮廓处理

Halcon 强大的算子亚像素提取轮廓。轮廓可进一步分割成直线或圆弧,然后提取参数如角度、中心或半径进行进一步的使用。
在这里插入图片描述

1 基本概念

提取轮廓的步骤:
在这里插入图片描述

1.1 提取轮廓XLD

利用感兴趣区域提取某些对象轮廓,在使用滤波时能够更好的找到一个轮廓。
在这里插入图片描述
提取轮廓也需充分考虑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绘制XLD轮廓。轮廓也可以从不同数据来源进行合成。如CAD数据,用户交互或测量,使用算子gen_contour_polygon_xld和gen_contour_polygon_rounded_xld转换为XLD轮廓。算子draw_xld和draw_xld_mode交互式绘制XLD轮廓。最后将区域边界转换为轮廓。

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 拟合处理

从轮廓中分割出直线、矩形、圆弧或椭圆弧时,可以通过调用其中算子来确定相应的参数,例如直线端的坐标或圆的圆心和半径。从轮廓中的线、圆或椭圆很接近直线、圆、椭圆。算子算法非常先进,获得的参数比较可靠。

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程序示例

* 通过拟合直线或圆检测零件
* 
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()

在这里插入图片描述
琐碎时间阅读基础知识,详情关注微信公众号“知识代码AI”。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值