1、2D测量简介
Halcon是一款工业视觉软件,提供了丰富的2D测量功能。通过2D测量,可以获取物体的范围、方向、角度、位置、尺寸和个数等特征。其中,Halcon的2D Metrology模块提供了亚像素级别的卡尺测量功能,可以测量的几何形状包括直线、圆、椭圆、矩形等。
通常,对于2D度量,必须提供要测量的对象的位置,方向和几何形状的近似值。在显示对象的图像内,这些近似对象的边界用于定位对象的真实边缘以适应几何形状的参数,使得它们最佳地适合图像数据。测量结果是优化的参数。计量模型用于存储所有必要的信息,例如计量对象的位置和几何形状的初始参数,控制测量的参数以及测量结果。
2D测量流程及涉及的主要算子如下:
2、相关算子详细介绍
2.1 创建测量模型
相关算子:
create_metrology_model() ——创建测量几何图形所需的数据结构/模型。
create_metrology_model( MetrologyHandle)
2.2 设置测量对象图像的大小
相关算子:
set_metrology_model_image_size() ——设置测量对象图像的大小
set_metrology_model_image_size( MetrologyHandle, Width, Height)
2.3 创建测量模型ROI
目的:提供近似值;将测量对象添加到模型中,同时将测量对象的近似参数和控制测量的参数添加到模型中。
相关算子:
① add_metrology_object_circle_measure() ——将圆或圆弧添加到度量模型中
add_metrology_object_circle_measure(
MetrologyHandle, //输入测量模型的句柄
Row, //输入圆心的行
Column, //输入圆心的列
Radius, //输入圆的半径
MeasureLength1, //输入垂直于边界的测量区域的一半长度;默认值:20,参考值:10,20,30
MeasureLength2, //输入与边界相切的测量区域的一半长度;默认值:5,参考值:3,5,10
MeasureSigma, //输入用于平滑的高斯函数的sigma;默认值:1,参考值:0.4,0.6,0.8,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0
MeasureThreshold, //输入测量阈值;默认值:30,参考值:5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 90.0, 110.0
GenParamName, //输入参数名称;参考: ‘distance_threshold’, ‘end_phi’, ‘instances_outside_measure_regions’, ‘max_num_iterations’, ‘measure_distance’, ‘measure_interpolation’, ‘measure_select’, ‘measure_transition’, ‘min_score’, ‘num_instances’, ‘num_measures’, ‘point_order’, ‘rand_seed’, ‘start_phi’
GenParamValue, //输入参数值;参考:1, 2, 3, 4, 5, 10, 20, ‘all’, ‘true’, ‘false’, ‘first’, ‘last’, ‘positive’, ‘negative’, ‘uniform’, ‘nearest_neighbor’, ‘bilinear’, ‘bicubic’
Index //输出创建测量对象的索引值
)
② add_metrology_object_ellipse_measure() ——将椭圆或椭圆弧添加到度量模型中
add_metrology_object_ellipse_measure(
MetrologyHandle, //输入测量模型的句柄
Row, //输入椭圆圆心的行
Column, //输入椭圆圆心的列
Phi, //输入椭圆角度
Radius1, //输入椭圆长半轴
Radius2, //输入椭圆短半轴
MeasureLength1, //输入垂直于边界的测量区域的一半长度;默认值:20,参考值:10,20,30
MeasureLength2, //输入与边界相切的测量区域的一半长度;默认值:5,参考值:3,5,10
MeasureSigma, //输入用于平滑的高斯函数的sigma;默认值:1,参考值:0.4,0.6,0.8,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0
MeasureThreshold, //输入测量阈值;默认值:30,参考值:5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 90.0, 110.0
GenParamName, //输入参数名称
GenParamValue, //输入参数值
Index //输出创建测量对象的索引值
)
③ add_metrology_object_line_measure() ——将直线添加到度量模型中
add_metrology_object_line_measure(
MetrologyHandle, //输入测量模型的句柄
RowBegin, //输入测量区域行坐标起点
ColumnBegin, //输入测量区域列坐标起点
RowEnd, //输入测量区域行坐标终点
ColumnEnd, //输入测量区域列坐标终点
MeasureLength1, //输入垂直于边界的测量区域的一半长度;默认值:20,参考值:10,20,30
MeasureLength2, //输入与边界相切的测量区域的一半长度;默认值:5,参考值:3,5,10
MeasureSigma, //输入用于平滑的高斯函数的sigma;默认值:1,参考值:0.4,0.6,0.8,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0
MeasureThreshold, //输入测量阈值;默认值:30,参考值:5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 90.0, 110.0
GenParamName, //输入参数名称
GenParamValue, //输入参数值
Index //输出创建测量对象的索引值
)
④ add_metrology_object_rectangle2_measure() ——将一个矩形添加到度量模型中
add_metrology_object_rectangle2_measure(
MetrologyHandle, //输入测量模型的句柄
Row, //输入矩形中心点行坐标
Column, //输入矩形中心点列坐标
Phi, //输入主轴 Phi 的方向, Phi 的输入值会自动映射到区间(-3.14 ,3.14)
Length1, //输入矩形较长的半边长 Length1
Length2, //输入矩形较短的半边长 Length2
MeasureLength1, //输入垂直于边界的测量区域的一半长度;默认值:20,参考值:10,20,30
MeasureLength2, //输入与边界相切的测量区域的一半长度;默认值:5,参考值:3,5,10
MeasureSigma, //输入用于平滑的高斯函数的sigma;默认值:1,参考值:0.4,0.6,0.8,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0
MeasureThreshold, //输入测量阈值;默认值:30,参考值:5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 90.0, 110.0
GenParamName, //输入参数名称
GenParamValue, //输入参数值
Index //输出创建测量对象的索引值
)
⑤ add_metrology_object_generic() ——将测量对象添加到测量模型中
add_metrology_object_generic(
MetrologyHandle, //输入测量模型的句柄
Shape, //输入要测量对象的类型;默认值:‘circle’,参考值:‘circle’,‘ellipse’,‘line’,‘rectangle2’
ShapeParam, //要添加的测量对象的参数
MeasureLength1, //输入垂直于边界的测量区域的一半长度;默认值:20,参考值:10,20,30;最小增量:1.0;建议增量:10.0
MeasureLength2, //输入与边界相切的测量区域的一半长度;默认值:5,参考值:3,5,10;最小增量:1.0;建议增量:10.0
MeasureSigma, //输入用于平滑的高斯函数的sigma;默认值:1,参考值:0.4,0.6,0.8,1.0,1.5,2.0,3.0,4.0,5.0,7.0,10.0;最小增量:0.01;建议增量:0.1;限制:(0.4 <= MeasureSigma)&&(MeasureSigma <= 100)
MeasureThreshold, //输入测量阈值/最小边缘幅度;默认值:30,参考值:5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 90.0, 110.0;最小增量:0.5;建议增量:2
GenParamName, //输入参数名称;参考: ‘distance_threshold’, ‘end_phi’, ‘instances_outside_measure_regions’, ‘max_num_iterations’, ‘measure_distance’, ‘measure_interpolation’, ‘measure_select’, ‘measure_transition’, ‘min_score’, ‘num_instances’, ‘num_measures’, ‘point_order’, ‘rand_seed’, ‘start_phi’
GenParamValue, //输入参数值;参考:1, 2, 3, 4, 5, 10, 20, ‘all’, ‘true’, ‘false’, ‘first’, ‘last’, ‘positive’, ‘negative’, ‘uniform’, ‘nearest_neighbor’, ‘bilinear’, ‘bicubic’
Index //输出创建测量对象的索引值
)
2.4 设置测量(模型/对象)参数
相关算子:
① set_metrology_model_param() ——设置测量模型的参数
set_metrology_model_param(
MetrologyHandle, //输入测量模型的句柄
GenParamName, //输入参数名称;参考: ‘camera_param’,输入相机参数由GenParamName= 'camera_param’指定,CameraParam是相机;‘plane_pose’(是否相机三维姿态);‘reference_system’(根据图像坐标系的平移(行、列)和旋转角度(角度),定义一种新的参考系统);‘scale’(期望单位与原始单位的比率);
GenParamValue //输入参数值;参考:1.0, 0.1, ‘m’, ‘cm’, ‘mm’, ‘microns’, ‘um’;
)
② set_metrology_object_param() ——为测量模型的测量对象设置参数
set_metrology_object_param(
MetrologyHandle, //输入测量模型的句柄
Index, //指定测量对象,为all时所有计量对象的参数都被设置(‘all’)
GenParamName, //输入参数名称;默认:‘num_instances’,参考:'distance_threshold', 'instances_outside_measure_regions', 'max_num_iterations', 'measure_distance', 'measure_interpolation', 'measure_length1', 'measure_length2', 'measure_select', 'measure_sigma', 'measure_threshold', 'measure_transition', 'min_score', 'num_instances', 'num_measures', 'rand_seed'
GenParamValue //输入参数值;默认:1,参考:1, 2, 3, 4, 5, 10, 20, ‘all’, ‘true’, ‘false’, ‘first’, ‘last’, ‘positive’, ‘negative’, ‘uniform’, ‘nearest_neighbor’, ‘bilinear’, ‘bicubic’
)
其中GenParamName参数名称
'measure_length1':区域,垂直于边界的测量区域的一半长度
'measure_length2':区域,相切于边界的测量区域的一半长度
'measure_distance':区域,两个测量区域中心之间的距离
'num_measures':区域,测量区域数
'measure_sigma':测量,用于平滑的高斯函数的 Sigma
'measure_threshold':测量,最小边缘幅度阈值
'measure_select':测量,边缘端点的选择('last'、'first')
'measure_transition':测量,方向('all'、'negative'、 'positive'),正边缘(暗->亮);负边缘(亮->暗)
'measure_interpolation':测量,插值类型
'min_score':拟合,最小分数
'num_instances':拟合,成功拟合实例的最大数量
'distance_threshold':拟合,距离阈值
2.5 校准测量模型
相关算子:
align_metrology_model() ——测量模型的对齐/校准
align_metrology_model(
MetrologyHandle, //输入测量模型的句柄
Row, //对齐测量模型的行坐标
Column, //对齐测量模型的列坐标
Angle,//对齐测量模型的旋转角度
)
2.6 应用测量
相关算子:
apply_metrology_model() ——测量并拟合计量模型中所有计量对象的几何形状
apply_metrology_model(
Image, //输入的测量图像
MetrologyHandle //输入测量模型的句柄
)
2.7 获取测量结果
相关算子:
① get_metrology_object_result() ——获取测量模型的测量结果
get_metrology_object_result(
MetrologyHandle, //输入测量模型的句柄
Index, //输出测量对象的索引;默认值:‘all’,参考:‘all’,0,1,2
Instance, //输入测量对象的实例;默认值:‘all’,参考:‘all’,0,1,2
GenParamName, //输入参数名称;默认值:‘result_type’,参考:‘angle_direction’,‘result_type’,‘used_edges’
GenParamValue, //输入参数值;默认值:‘all_param’,参考:‘all_param’, ‘score’, ‘true’, ‘false’, ‘row’, ‘column’, ‘amplitude’, ‘radius’, ‘phi’, ‘radius1’, ‘radius2’, ‘length1’, ‘length2’, ‘row_begin’, ‘column_begin’, ‘row_end’, ‘column_end’, ‘nrow’, ‘ncolumn’, ‘distance’, ‘x’, ‘y’, ‘x_begin’, ‘y_begin’, ‘x_end’, ‘y_end’, ‘nx’, ‘ny’, ‘positive’, ‘negative’
Parameter//输出结果值
)
其中
GenParamName:
(1)‘result_type’:如果GenParamName设置为’result_type’,则GenParamValue允许控制计量对象的返回方式和结果。
(2)‘angle_direction’:该参数确定由拟合产生的角度的旋转方向。将参数’angle_direction’设置为’正’,在物体的主轴和坐标系的水平轴之间以数学正方向(逆时针方向)指定角度。将参数’angle_direction’设置为’负’,在对象的主轴和坐标系的水平轴之间沿数学负方向(顺时针)指定角度。角度的结果以弧度返回。
默认值:‘正面’,参考:‘正面’,‘负面’;
(3)‘used_edges’:要查询实际用于拟合度量对象的边缘点,可以选择以下GenParamValue值:
‘行’:返回用于拟合度量对象的边的行坐标。
‘列’:返回用于拟合度量对象的边的列坐标。
‘振幅’:返回用于拟合度量对象的边缘的边缘幅度。
GenParamValue:
如果GenParamValue设置为’all_param’,则返回计量对象的所有测量参数。
对于圆,返回值是中心的坐标和圆的半径。顺序分别是[‘row’,‘column’,‘radius’]或[‘x’,‘y’,‘radius’]。
对于椭圆,返回值是中心的坐标,长轴’phi’的方向,较大半轴’radius1’的长度,以及椭圆的较小半轴’radius2’的长度。顺序分别是[‘row’,‘column’,‘phi’,‘radius1’,‘radius2’]或[‘x’,‘y’,‘phi’,‘radius1’,‘radius2’]。
对于一条线,返回该线的起点和终点。顺序是[‘row_begin’,‘column_begin’,‘row_end’,‘column_end’]或[‘x_begin’,‘y_begin’,‘x_end’,‘y_end’]
对于矩形,返回值是中心的坐标,主轴’phi’的方向,较大的半边’length1’的长度,以及矩形的较小半边’length2’的长度。顺序分别是[‘row’,‘column’,‘phi’,‘length1’,‘length2’]或[‘x’,‘y’,‘phi’,‘length1’,‘length2’]。
② get_metrology_object_measures() ——获取测量区域和测量模型的测量对象的边缘位置结果
get_metrology_object_measures(
Contours, //输出测量对象测量区域的矩形XLD轮廓
MetrologyHandle, //输入测量模型的句柄
Index, //输出测量对象的索引;默认值:‘all’,参考:‘all’,0,1,2
Transition, //输入选择浅色/深色或深色/浅色边缘;默认值:‘all’,可选:‘全部’,‘负面’,‘正面’
Row, //输出测量边缘的行坐标
Column //输出测量边缘的列坐标
)
③ get_metrology_object_result_contour() ——查询(获取)测量对象的结果轮廓
get_metrology_object_result_contour(
Contour, //输出给定测量对象的结果轮廓
MetrologyHandle, //输入测量模型的句柄
Index, //输出测量对象的索引;默认值:‘all’,参考:‘all’,0,1,2
Instance, //输入测量对象的实例;默认值:‘all’,参考:‘all’,0,1,2
Resolution //输入相邻轮廓点之间的距离;默认值:1.5,参考:Resolution >= 1.192e-7
)
2.8 释放测量模型
相关算子:
clear_metrology_model() —— 删除测量模型并释放分配的内存
3、2D测量实战
精确测量下列图像中圆和矩形
实现代码:
* 实现圆和矩形的测量
****************************第一步:图像显示初始化****************************
* Display initializations
dev_update_off ()
read_image (Image, 'pads')
*获取图像宽和高
get_image_size (Image, Width, Height)
dev_close_window ()
*打开一个新的图像窗口,该窗口保留给定图像的长宽比
*打开具有给定最小和最大范围的新图形窗口,以便保留给定图像的纵横比。
*WidthLimit设置为-1,则使用以下默认值:[500,800]。
*HeightLimit设置为-1,则使用以下默认值:[400,600]。
*如果根据窗口宽高限制无法创建窗口,则忽略最小窗口大小的限制
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
*用来设置当前窗口的字体属性
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
****************************第二步:定义近似的位置和测量圆圈的公差,其实就是手动设置圆存在的中心点位置****************************
*圆心横坐标设定,输出:[52, 141, 230, 319, 408, 497] 从52开始,到500结束,每个数等于前一个数加89
RowCircle := [52:89:500]
*输出:[52, 141, 230, 319, 408, 497, 52, 141, 230, 319, 408, 497] 合并2个数组(此处是分成两列的行值)
CircleInitRow := [RowCircle,RowCircle]
*gen_tuple_const(6,348) 输出:[348, 348, 348, 348, 348, 348] 生成6个相同值的数组
CircleInitColumn := [gen_tuple_const(6,348),gen_tuple_const(6,438)]
*cross生成轮廓,Row行坐标,Col列坐标,Size十字型长度,Angle十字形方向
gen_cross_contour_xld (Cross1, CircleInitRow, CircleInitColumn, 6, 0.785398)
*定义半径,gen_tuple_const(n,m) 创建一个具有n个元素的,每个元素都为m的数据
CircleInitRadius := [gen_tuple_const(6,23),gen_tuple_const(6,23)]
*环状区域宽度可允许范围
CircleRadiusTolerance := 12
****************************第三步:定义近似的位置和测量矩形的公差,设置矩形的轮廓区域****************************
*矩形中心点行坐标
RectangleInitRow := [410,410]
* 矩形中心点列坐标(数量和ROW相同)
RectangleInitColumn := [215,562]
*矩形起始角度
RectangleInitPhi := [0,0]
*矩形行长的一半
RectangleInitLength1 := [85,85]
*矩形列长的一半
RectangleInitLength2 := [88,88]
*矩形测量的环状区域宽度
RectangleTolerance := 10
*
****************************第四步:创建测量模型****************************
create_metrology_model (MetrologyHandle)
****************************第五步:设置测量模型的待检测图像的宽高(提升检测时间)****************************
set_metrology_model_image_size (MetrologyHandle, Width, Height)
****************************第六步:将上面的矩形对象添加到测量模型中****************************
add_metrology_object_rectangle2_measure (MetrologyHandle, RectangleInitRow, RectangleInitColumn, RectangleInitPhi, RectangleInitLength1, RectangleInitLength2, RectangleTolerance, 5, .5, 1, [], [], MetrologyRectangleIndices)
****************************第七步:将上面的圆形对象添加到测量模型中****************************
add_metrology_object_circle_measure (MetrologyHandle, CircleInitRow, CircleInitColumn, CircleInitRadius, CircleRadiusTolerance, 5, 1.5, 2, [], [], MetrologyCircleIndices)
****************************第八步:设置测量模型对象的检测对象相关参数(每个计量对象可以测量一个以上的圆/矩形/线/椭圆)****************************
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'num_instances', 2)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_transition', 'uniform')
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'min_score', .9)
****************************第九步:实施测量****************************
apply_metrology_model (Image, MetrologyHandle)
****************************第十步:获取测量结果****************************
get_metrology_object_result (MetrologyHandle, MetrologyRectangleIndices, 'all', 'result_type', 'all_param', RectangleParameter)
*这里要知道RectangleParameter检测结果参数的数据结构信息
* Extract the parameters for better readability
Sequence := [0:5:|RectangleParameter| - 1]
RectangleRow := RectangleParameter[Sequence]
RectangleColumn := RectangleParameter[Sequence + 1]
RectanglePhi := RectangleParameter[Sequence + 2]
RectangleLength1 := RectangleParameter[Sequence + 3]
RectangleLength2 := RectangleParameter[Sequence + 4]
*获取圆形检测结果
get_metrology_object_result (MetrologyHandle, MetrologyCircleIndices, 'all', 'result_type', 'all_param', CircleParameter)
* Extract the parameters for better readability
Sequence := [0:3:|CircleParameter| - 1]
CircleRow := CircleParameter[Sequence]
CircleColumn := CircleParameter[Sequence + 1]
CircleRadius := CircleParameter[Sequence + 2]
*
* Display the results
*
* 获取测量conturs
get_metrology_object_result_contour (Contours, MetrologyHandle, 'all', 'all', 1.5)
*获取到检测区域的conturs,以及轮廓坐标,并根据这些坐标去拟合成圆或矩形
get_metrology_object_measures (Contour, MetrologyHandle, 'all', 'all', Row1, Column1)
gen_cross_contour_xld (Cross, Row1, Column1, 6, 0.785398)
* Display everything
Color := ['gray','cyan','green']
dev_display (Image)
dev_set_line_width (1)
dev_set_color (Color[0])
dev_display (Contour)
dev_set_color (Color[1])
dev_display (Cross)
dev_set_line_width (2)
dev_set_color (Color[2])
dev_display (Contours)
Message := Color[2] + ': Measurement result'
Message[1] := Color[1] + ': Edge candidate points'
Message[2] := Color[0] + ': Measure regions'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
stop ()
* Clean up memory
clear_metrology_model (MetrologyHandle)
实现结果: