HALCON算子get_metrology_object_result_contour全解析
一、算子核心定位
get_metrology_object_result_contour是HALCON 2D计量(2D Metrology)模块的可视化核心算子,核心功能是获取经apply_metrology_model拟合后的计量对象实例的结果轮廓(XLD形式)——它基于拟合后的几何参数(如圆的圆心/半径、矩形的中心/角度/尺寸)生成对应形状的亚像素XLD轮廓,是将抽象的测量数值转化为直观可视化轮廓的关键工具,常用于验证拟合结果的形状/位置是否符合预期。
二、算法核心原理
- 有效性校验:验证输入的计量模型句柄(MetrologyHandle)、计量对象索引(Index)、实例编号(Instance)的有效性,确保指向已完成拟合的计量对象/实例;
- 拟合参数读取:从计量模型中读取指定对象/实例的拟合几何参数(如圆的
row/column/radius、矩形的row/column/phi/length1/length2); - 轮廓生成:根据几何参数和
Resolution(相邻轮廓点距离),生成对应形状的亚像素XLD轮廓:- 圆形/椭圆:按分辨率均匀生成圆周/椭圆周的轮廓点;
- 矩形/直线:按分辨率生成边的轮廓点;
- 分辨率约束:若输入的
Resolution低于最小有效值(1.192e-7),自动将其重置为该最小值; - 结果返回:将生成的XLD轮廓按“先第一个对象的所有实例,再第二个对象的所有实例”的顺序封装为数组,输出到
Contour参数; - 无修改逻辑:仅生成并返回轮廓,不改变计量模型/对象的任何属性。
三、参数全详解
(一)输入参数(Input Parameters)
| 参数名 | 类型 | 功能说明 | 默认值 | 关键取值规则 | 注意事项 |
|---|---|---|---|---|---|
| MetrologyHandle | metrology_model → (handle) | 指定要查询的2D计量模型句柄 | - | 必须为已有效创建/加载的计量模型句柄 | 1. 需通过create_metrology_model生成,未被clear_metrology_model释放;2. 无效句柄直接抛出“句柄无效”异常 |
| Index | integer(-array) → (integer / string) | 指定要查询的计量对象索引 | 0 | 可选值: ▪ ‘all’:查询模型内所有计量对象的轮廓; ▪ 整数/整数数组:查询指定索引的计量对象(如0、[0,1]) | 整数索引必须是get_metrology_object_indices返回的有效索引,否则抛异常 |
| Instance | integer(-array) → (string / integer) | 指定要查询的实例编号 | ‘all’ | 可选值: ▪ ‘all’:查询指定计量对象的所有实例轮廓; ▪ 整数/整数数组:查询指定实例(如0、[0,1]) | 1. 实例编号从0开始,需≤get_metrology_object_num_instances返回的实例数-1;2. 若实例不存在(如指定1但仅检测到1个实例),抛异常 |
| Resolution | real → (real) | 轮廓相邻点的欧氏距离(像素) | 1.5 | 取值规则: ▪ 最小值:1.192e-7; ▪ 推荐值:1.0~5.0(兼顾精度与效率); ▪ 约束:Resolution ≥ 1.192e-7 | 1. 值越小,轮廓点越多、形状越精细,但生成速度越慢; 2. 低于最小值时,算子自动重置为1.192e-7 |
(二)输出参数(Output Parameters)
| 参数名 | 类型 | 功能说明 | 关联说明 |
|---|---|---|---|
| Contour | xld_cont(-array) → object | 返回拟合后的XLD轮廓数组 | 1. 每个实例对应一个XLD轮廓; 2. 轮廓坐标为图像像素坐标(不受相机参数影响); 3. 顺序:先第一个计量对象的所有实例,再第二个计量对象的所有实例; 4. 可直接用 dev_display可视化 |
四、使用关键注意事项
- 执行时序约束:必须在调用
apply_metrology_model(完成拟合)后调用本算子,否则Contour返回空数组;若拟合未找到目标(实例数为0),也返回空数组; - 分辨率权衡:
- 高分辨率(小值,如0.5):轮廓更精细,适合高精度可视化,但生成耗时更长;
- 低分辨率(大值,如5.0):轮廓点数少,生成快,适合快速预览;
- 默认值1.5是“精度-效率”的平衡值,满足大部分场景需求;
- 坐标特性:生成的轮廓始终以像素为单位,即使设置了相机参数/测量平面(公制坐标),也不会转换为公制,仅反映图像中的像素位置;
- 多线程特性:
- 多线程类型:可重入(能与非排他算子并行运行);
- 多线程范围:全局(可从任意线程调用);
- 无并行优化:仅单线程生成轮廓,无性能加速;
- 返回值规则:执行成功返回
2(H_MSG_TRUE),参数无效(如索引/实例错误、Resolution低于最小值且未自动修正)时直接抛出异常。
五、算子调用链路
(一)前置算子(Possible Predecessors)
create_metrology_model:创建空的2D计量模型(基础前置);add_metrology_object_*(如add_metrology_object_rectangle2_measure/add_metrology_object_circle_measure):向模型添加计量对象;apply_metrology_model:执行检测拟合(生成轮廓的必要前置);get_metrology_object_num_instances:(可选)获取实例数,用于精准指定Instance。
(二)后置算子(Possible Successors)
dev_display:可视化显示轮廓,验证拟合结果的形状/位置;gen_region_contour_xld:将XLD轮廓转化为区域,用于后续形态学操作;clear_metrology_model:释放计量模型句柄(收尾操作)。
六、与相似算子的核心差异
| 算子名称 | 核心区别 | 适用场景 |
|---|---|---|
get_metrology_object_result_contour | 返回拟合后的目标轮廓XLD(基于拟合参数生成) | 可视化拟合结果的形状/位置、验证拟合精度 |
get_metrology_object_result | 返回拟合后的数值参数(如圆心、半径、角度) | 获取精准的测量数值、用于尺寸判定/计算 |
get_metrology_object_measures | 返回测量区域轮廓+原始边缘点坐标(无拟合逻辑) | 调试测量区域范围、验证原始边缘检测结果 |
七、典型应用示例(HDevelop 代码)
*This example shows the usage of the metrology model*to measure circles and rectangles with subpixel*accuracy under challenging conditions easily.**Display initializationsdev_update_off()read_image(Image,'pads')get_image_size(Image,Width,Height)dev_close_window()dev_open_window_fit_image(Image,0,0,-1,-1,WindowHandle)set_display_font(WindowHandle,14,'mono','true','false')**Define the approximate position and the measure*toleranceforthe circles RowCircle:=[52:89:500]CircleInitRow:=[RowCircle,RowCircle]CircleInitColumn:=[gen_tuple_const(6,348),gen_tuple_const(6,438)]gen_cross_contour_xld(Cross1,CircleInitRow,CircleInitColumn,6,0.785398)CircleInitRadius:=[gen_tuple_const(6,23),gen_tuple_const(6,23)]CircleRadiusTolerance:=12*Define the approximate position and the measure*toleranceforthe rectangles2 RectangleInitRow:=[410,410]RectangleInitColumn:=[215,562]RectangleInitPhi:=[0,0]RectangleInitLength1:=[85,85]RectangleInitLength2:=[88,88]RectangleTolerance:=10**Prepare the metrology model data structurecreate_metrology_model(MetrologyHandle)*Setting the image width in advance is not*necessary,but improves the runtime of the*first measurement.set_metrology_model_image_size(MetrologyHandle,Width,Height)*Add the metrology rectangle objects to the model*as defined aboveadd_metrology_object_rectangle2_measure(MetrologyHandle,RectangleInitRow,RectangleInitColumn,RectangleInitPhi,RectangleInitLength1,RectangleInitLength2,RectangleTolerance,5,.5,1,[],[],MetrologyRectangleIndices)*Add the metrology circle objects to the model*as defined aboveadd_metrology_object_circle_measure(MetrologyHandle,CircleInitRow,CircleInitColumn,CircleInitRadius,CircleRadiusTolerance,5,1.5,2,[],[],MetrologyCircleIndices)*It is possible to measure more than one circle/rectangle/line/ellipse*instance per metrology object in one call.*Since we like to measure two circles per object,*we set'num_instances'to2.set_metrology_object_param(MetrologyHandle,MetrologyCircleIndices,'num_instances',2)*Setting'measure_transition'to'uniform'assures*that only consistent circles are returned,that have*either only edges from bright to dark or vice versa.*Since the consistency check increases runtime,it is*switched of bydefault.*In this example however,it is safer toswitchit on,*because both negative and positive edges are present.set_metrology_object_param(MetrologyHandle,MetrologyCircleIndices,'measure_transition','uniform')*Setting the minimum score can make the results more robustset_metrology_object_param(MetrologyHandle,MetrologyCircleIndices,'min_score',.9)**Perform the measurement*apply_metrology_model(Image,MetrologyHandle)*get_metrology_object_result(MetrologyHandle,MetrologyRectangleIndices,'all','result_type','all_param',RectangleParameter)*Extract the parametersforbetter 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]**Access the results of the circle measurementget_metrology_object_result(MetrologyHandle,MetrologyCircleIndices,'all','result_type','all_param',CircleParameter)*Extract the parametersforbetter readability Sequence:=[0:3:|CircleParameter|-1]CircleRow:=CircleParameter[Sequence]CircleColumn:=CircleParameter[Sequence+1]CircleRadius:=CircleParameter[Sequence+2]**Display the results**Get measured contoursget_metrology_object_result_contour(Contours,MetrologyHandle,'all','all',1.5)*Get the contours of the measure regions*and the coordinates of the edge points*that were the basisforfitting the circles and rectanglesget_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 memoryclear_metrology_model(MetrologyHandle)八、总结
关键点回顾
get_metrology_object_result_contour核心作用是基于拟合参数生成可视化XLD轮廓,是将数值测量结果转化为直观形状的关键工具;Resolution控制轮廓精细度(值越小越精细),最小值为1.192e-7,低于该值会自动重置;- 轮廓始终以像素坐标返回,需在
apply_metrology_model后调用,否则返回空轮廓。