一、提要
对于官方帮助文件的案例,需要逐一跟踪代码,掌握这些技能不很容易,因为这需要多种算子互相搭配,可以说每一个案例都针对一个测量场景,因此,学习halcon不要从一个一个算子做起,而要从案例做起。因为具体问题不同,方法也不同,比如,地图的边缘提取,和加工零件的边缘提取做法有不同,注意这种细节。
二、必要的算子介绍
2.1 dev_set_draw
dev_set_draw 定义区域的填充模式。如果 DrawMode 设置为“filled”,则区域显示为填充,如果设置为“margin”,则仅显示轮廓。在 'margin' 模式下,轮廓的外观会受到 dev_set_line_width、set_line_approx 和 set_line_style 的影响。
1)算子形式
dev_set_draw( : : DrawMode : )
2)参数描述
DrawMode参数两个选项(“filled”,和 “margin”),设定完后,显示区域方式就变了,如图:
.2 area_center
获得区域的面积和中心位置。
运算符 area_center 计算输入区域的面积和中心。面积定义为一个区域的像素数。中心分别计算为所有像素的行坐标或列坐标的平均值。如果传递了多个区域,则结果存储在元组中,元组中值的索引对应于输入区域的索引。在空白区域的情况下,如果没有设置其他行为,则所有参数的值都为 0.0(参见 set_system)。
1)算子形式
area_center(Regions : : : Area, Row, Column)
2)参数描述
Regions :输入区域
Area, 区域面积
Row, 行坐标
Column,列坐标
2.3 orientation_region
运算符orientation_region 计算区域的方向。运算符基于 elliptic_axis。此外,计算轮廓上与重心距离最大的点。如果在旋转坐标系中,该点的列坐标小于重心的列坐标,则将 的值加到角度上。如果传递了多个区域,则结果存储在元组中,元组中值的索引对应于输入中区域的索引。
1)算子形式
orientation_region(Regions : : : Phi)
2)参数描述
Regions :输入区域
Phi, 输出角度,就是区域不对称的旋转角度。也就是外接矩形的角
disp_cross (WindowID, RowCenterRegion, ColumnCenterRegion, 15, 0)
disp_arrow (WindowID, RowCenterRegion, ColumnCenterRegion, RowCenterRegion - 60 * sin(OrientationRegion), ColumnCenterRegion + 60 * cos(OrientationRegion), 2)
显示十字叉、箭头。
三、边缘提取算子
3.1 edges_sub_pix
edges_sub_pix 使用递归实现的滤波器(根据 Deriche、Lanser 和 Shen)或 Canny 提出的传统实现的“高斯导数”滤波器(使用滤波器掩码)检测阶梯边缘。
1)算子形式
edges_sub_pix(Image : Edges : Filter, Alpha, Low, High : )
2)参数解释
Image : 输入图像
Edges : 输出边缘像素
Filter,:算法选择,可选择算法是【'deriche1', 'lanser1', 'deriche2', 'lanser2', 'shen', 'mshen', 'canny', 'sobel', and 'sobel_fast'】
Alpha,
Low,
High :
3)参数详细
edges_sub_pix 使用递归实现的滤波器(根据 Deriche、Lanser 和 Shen)或 Canny 提出的传统实现的“高斯导数”滤波器(使用滤波器掩码)检测阶梯边缘。因此,可以使用以下边缘运算符:“deriche1”、“lanser1”、“deriche2”、“lanser2”、“shen”、“mshen”、“canny”、“sobel”和“sobel_fast”
(参数过滤器)。
提取的边缘在 Edges 中作为亚像素精确的 XLD 轮廓返回。对于除 'sobel_fast' 之外的所有边缘运算符,为每个边缘点定义了以下属性(参见 get_contour_attrib_xld):
'edge_direction' 边缘方向
'angle' 法线向量到轮廓的方向(当轮廓从起点到终点遍历时,法线向量指向轮廓的右侧;角度是相对于图像的行轴给出的) .)
“响应”边缘幅度(梯度幅度)
除了'sobel'和'sobel_fast'之外的所有边缘算子的“滤波器宽度”(即平滑量)可以任意选择,可以通过调用info_edges来估计参数Alpha的具体值。对于所有过滤器(Deriche、Lanser 和 Shen 过滤器),“过滤器宽度”随着 Alpha 的增加而减小。唯一的例外是 Canny 过滤器,其中增加的 Alpha 也会导致“过滤器宽度”的增加。“宽”滤波器对噪声表现出更大的不变性,但检测小细节的能力也有所下降。非递归过滤器,例如 Canny 过滤器,是使用过滤器掩码实现的,因此增加过滤器宽度会增加执行时间。相反,递归过滤器的执行时间不取决于过滤器的宽度。因此,使用 Derche、Lanser 和 Shen 过滤器可以实现任意过滤器宽度,而不会增加操作员的运行时间。与 Canny 算子相比,由此产生的速度优势自然会随着更大的过滤器宽度而增加。作为边界处理,递归算子假设图像在图像之外为零,而 Canny 算子在图像边界处重复灰度值。可通过以下 Alpha 选择获得可比较的过滤器宽度:
3.2 get_contour_attrib_xld
获取线段的属性特征参数值。
1)算子格式
get_contour_attrib_xld(Contour : : Name : Attrib)
2)参数解释
Contour:输入曲线对象XLD
Name:属性名称,值域为【 'regr_norm_row', 'regr_norm_col', 'regr_mean_dist', 'regr_dev_dist', 'cont_approx', 'bright_dark', 'is_hole'】
Attrib:输出属性值,1表示肯定,0表示否定
3)参数详细
用query_contour_global_attribs_xld(SingleSegment,Attribs)函数可以获取属性,只有【cont_approx】一项,因此,其它选项都不能用。
Name参数的值的意义:
cont_approx:有曲率的曲线,此时,Attrib=-1,直线;Attrib=0,椭圆;Attrib=1,圆
四、距离测量项目
4.1 项目描述
在下列工件中,测量出四个圆周的圆心之间距离。项目需要以下知识点:
如何区域生成?
如何边缘提取?
如何xld生成
如何xld分段?
xld分段如何访问?
如何获取曲线特征参数?
如何中心点距离测量?
4.2 参考代码
read_image (Image, 'metal-parts/metal-parts-01')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'light gray', WindowID)
dev_set_draw ('fill')
threshold (Image, Region, 100, 255)
clear_window(WindowID)
disp_region(Region, WindowID)
edges_sub_pix (Image, Edges, 'canny', 0.6, 30, 70)
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 6, 4, 4)
dev_clear_window ()
dev_set_colored (12)
dev_display (ContoursSplit)
count_obj (ContoursSplit, NumSegments)
dev_display (Image)
NumCircles := 0
RowsCenterCircle := []
ColumnsCenterCircle := []
for i := 1 to NumSegments by 1
select_obj (ContoursSplit, 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_circle_contour_xld (ContCircle, Row, Column, Radius, 0, rad(360), 'positive', 1)
RowsCenterCircle := [RowsCenterCircle,Row]
ColumnsCenterCircle := [ColumnsCenterCircle,Column]
dev_display (ContCircle)
endif
endfor
distance_pp (RowsCenterCircle[1], ColumnsCenterCircle[1], RowsCenterCircle[2], ColumnsCenterCircle[2], Distance_2_3)
distance_pp (RowsCenterCircle[0], ColumnsCenterCircle[0], RowsCenterCircle[2], ColumnsCenterCircle[2], Distance_1_3)
distance_pp (RowsCenterCircle[3], ColumnsCenterCircle[3], RowsCenterCircle[4], ColumnsCenterCircle[4], Distance_4_5)
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !