HALCON算子get_metrology_object_result全解析
一、算子核心定位
get_metrology_object_result是HALCON 2D计量(2D Metrology)模块的核心结果读取算子,也是获取最终测量数据的核心入口。其核心功能是读取经apply_metrology_model检测拟合后,指定计量对象/实例的具体测量结果——包括几何参数(如圆心、半径、矩形角度)、拟合分数、所用边缘点坐标/振幅,还可控制角度返回方向,是从2D计量模型中提取精准测量数据的关键算子。
二、算法核心原理
- 参数校验:验证计量模型句柄(MetrologyHandle)、计量对象索引(Index)、实例编号(Instance)的有效性,确保参数匹配模型内的实际对象/实例;
- 结果类型解析:根据
GenParamName(通用参数名)和GenParamValue(通用参数值)的组合,确定要读取的结果类型(如全部几何参数、单个参数、拟合分数、所用边缘点); - 结果提取:
- 若读取几何参数:提取拟合后的计量对象实例参数(像素/公制坐标,取决于相机参数是否设置);
- 若读取分数:计算“实际用于拟合的测量数/最大测量区域数”的比值;
- 若读取所用边缘点:提取参与拟合的边缘点坐标/振幅;
- 若控制角度方向:按指定旋转方向(顺时针/逆时针)转换角度值;
- 结果封装:按“先第一个计量对象的所有实例,再第二个计量对象的所有实例”的顺序,将结果封装为数组输出到
Parameter; - 无修改逻辑:仅读取检测拟合结果,不改变模型/对象的任何属性。
三、参数全详解
(一)输入参数(Input Parameters)
| 参数名 | 类型 | 功能说明 | 默认值 | 关键取值规则 | 注意事项 |
|---|---|---|---|---|---|
| MetrologyHandle | metrology_model → (handle) | 指定要查询的2D计量模型句柄 | - | 必须为已有效创建/加载的计量模型句柄 | 需通过create_metrology_model生成,未被clear_metrology_model释放,无效句柄抛异常 |
| Index | integer(-array) → (integer / string) | 指定要查询的计量对象索引 | 0 | 可选值: ▪ ‘all’:查询所有计量对象; ▪ 整数/整数数组:查询指定索引(如0、[0,1]) | 整数索引需为get_metrology_object_indices返回的有效索引 |
| Instance | integer(-array) → (string / integer) | 指定要查询的实例编号 | ‘all’ | 可选值: ▪ ‘all’:查询指定计量对象的所有实例; ▪ 整数/整数数组:查询指定实例(如0、[0,1]) | 实例编号从0开始,需≤get_metrology_object_num_instances返回的实例数-1 |
| GenParamName | attribute.name-array → (string) | 通用参数名(控制结果类型) | ‘result_type’ | 可选值: ▪ ‘result_type’:读取几何参数/拟合分数; ▪ ‘used_edges’:读取参与拟合的边缘点; ▪ ‘angle_direction’:控制角度返回方向 | 可传入数组(如[‘result_type’,‘angle_direction’]),需与GenParamValue长度一致 |
| GenParamValue | attribute.value-array → (string / real) | 通用参数值(匹配GenParamName) | ‘all_param’ | 核心组合规则: 1. GenParamName='result_type'时:- ‘all_param’:返回所有几何参数; - ‘score’:返回拟合分数; - 单个参数名(如’radius’/‘phi’):返回指定参数; 2. GenParamName='used_edges'时:- ‘row’/‘column’/‘amplitude’:返回边缘点行/列坐标/振幅; 3. GenParamName='angle_direction'时:- ‘positive’(默认):逆时针角度; - ‘negative’:顺时针角度 | 多参数组合时,GenParamName和GenParamValue需一一对应(如[‘result_type’,‘angle_direction’], [‘radius’,‘negative’]) |
(二)输出参数(Output Parameters)
| 参数名 | 类型 | 功能说明 | 关联说明 |
|---|---|---|---|
| Parameter | real(-array) → (real / integer / string) | 返回指定类型的测量结果数组 | 1. 结果顺序:先第一个计量对象的所有实例,再第二个计量对象的所有实例; 2. 坐标类型:未设置相机参数时返回像素坐标(row/column),设置后返回公制坐标(x/y); 3. 角度单位:弧度,方向由 angle_direction控制 |
补充:不同计量对象的all_param返回顺序
| 计量对象类型 | 像素坐标返回顺序 | 公制坐标返回顺序 |
|---|---|---|
| 圆(Circle) | [row, column, radius] | [x, y, radius] |
| 椭圆(Ellipse) | [row, column, phi, radius1, radius2] | [x, y, phi, radius1, radius2] |
| 线(Line) | [row_begin, column_begin, row_end, column_end] | [x_begin, y_begin, x_end, y_end] |
| 矩形(Rectangle2) | [row, column, phi, length1, length2] | [x, y, phi, length1, length2] |
四、使用关键注意事项
- 执行时序约束:必须在调用
apply_metrology_model(执行检测拟合)后调用,否则Parameter返回空数组; - 坐标类型规则:
- 未设置相机参数/测量平面:返回像素坐标(row/column/nrow/ncolumn);
- 设置相机参数+测量平面:返回公制坐标(x/y/nx/ny);
- 结果顺序规则:批量查询时,结果按“1st实例 of 1st对象 → 2nd实例 of 1st对象 → 1st实例 of 2nd对象 → …”排列;
- 角度相关:
- 角度单位为弧度,默认逆时针(positive),可设为顺时针(negative);
- 仅对椭圆/矩形的
phi参数生效;
- 多线程特性:
- 多线程类型:可重入(能与非排他算子并行运行);
- 多线程范围:全局(可从任意线程调用);
- 无并行优化:单线程读取数据;
- 拟合分数含义:分数=“用于拟合的测量数/最大测量区域数”,值越高表示拟合质量越好(越接近1);
- 返回值规则:执行成功返回
2(H_MSG_TRUE),参数无效(如索引/实例错误)时抛异常。
五、算子调用链路
(一)前置算子(Possible Predecessors)
create_metrology_model:创建空2D计量模型(基础);add_metrology_object_*(如add_metrology_object_circle_measure):添加计量对象;set_metrology_object_param:(可选)设置num_instances(多实例检测);apply_metrology_model:执行检测拟合(必要前置);get_metrology_object_num_instances:(可选)获取实例数,用于遍历读取结果。
(二)后置算子(Possible Successors)
clear_metrology_model:释放计量模型句柄(收尾);dev_print_var:打印测量结果(验证/日志);gen_contour_circle_xld:根据圆参数生成XLD轮廓(可视化);gen_contour_rectangle2_xld:根据矩形参数生成XLD轮廓(可视化)。
六、与相似算子的核心差异
| 算子名称 | 核心区别 | 适用场景 |
|---|---|---|
get_metrology_object_result | 返回拟合后的最终测量结果(几何参数/分数/所用边缘点) | 获取目标的精准测量参数(如圆心、半径)、评估拟合质量 |
get_metrology_object_measures | 返回原始边缘点坐标+测量区域轮廓,无拟合逻辑 | 调试测量区域、验证原始边缘检测结果 |
get_metrology_object_num_instances | 仅返回实例数量,无具体测量数据 | 统计检测到的目标数量、判断目标是否存在 |
get_metrology_object_result_contour | 返回拟合后的目标轮廓XLD(可视化用) | 直观展示拟合后的目标形状/位置 |
七、典型应用示例(HDevelop 代码)
*This example program shows how to align images based on point-to-line*correspondences.HALCON's metrology model and point_line_to_hom_mat2d are used*to detect the position and angle of the print in the images.The found position*and angle are used to transform the images to the referenceposition(the*position of the print in the first image in this example).*From the aligned images of correct prints,a variation model is constructed.*This variation model is then used to check and classify images of correct and*incorrect prints.dev_update_off()read_image(Image,'pen/pen-01')get_image_size(Image,Width,Height)dev_close_window()dev_open_window(0,Width+12,Width,Height,'black',WindowHandle)dev_open_window(0,0,Width,Height,'black',WindowHandleAlign)set_display_font(WindowHandle,14,'mono','true','false')set_display_font(WindowHandleAlign,14,'mono','true','false')dev_set_color('red')dev_display(Image)*Note:the checking of the print will be restricted to the region of the clip.*Sometimes the print is also in an incorrect position of the clip.This will lead*to erroneous regions at the top or bottom border of the clip and hence can*be detected easily.threshold(Image,Region,100,255)fill_up(Region,RegionFillUp)erosion_rectangle1(RegionFillUp,RegionROI,1,15)*Set up the metrology model with four lines.Four lines are used since this is*the minimum number of point-to-line correspondences that results in a unique rigid*transformation.create_metrology_model(MetrologyHandle)set_metrology_model_image_size(MetrologyHandle,Width,Height)add_metrology_object_line_measure(MetrologyHandle,[208,137,213,90],[49,327,139,307],[100,201,214,89],[82,318,56,375],40,5,1,30,['measure_transition','min_score'],['negative',0.5],Index)*Apply the metrology model to the reference image and read out the results.apply_metrology_model(Image,MetrologyHandle)get_metrology_object_result(MetrologyHandle,'all','all','result_type','row_begin',RowBegin)get_metrology_object_result(MetrologyHandle,'all','all','result_type','column_begin',ColBegin)get_metrology_object_result(MetrologyHandle,'all','all','result_type','row_end',RowEnd)get_metrology_object_result(MetrologyHandle,'all','all','result_type','column_end',ColEnd)*The reference points of the model are the center points of the detected line*segments.They will be used to compute the transformation from the current image*to the reference image using point_line_to_hom_mat2d below.RowRef:=0.5*(RowBegin+RowEnd)ColRef:=0.5*(ColBegin+ColEnd)dev_set_window(WindowHandle)dev_display(Image)dev_set_window(WindowHandleAlign)dev_display(Image)get_metrology_object_measures(MeasureContours,MetrologyHandle,'all','all',Row,Column)dev_set_color('green')dev_display(MeasureContours)dev_set_color('green')disp_message(WindowHandleAlign,['Measure objects of the four','metrology line objects'],'window',12,12,'black','true')disp_continue_message(WindowHandle,'black','true')stop()dev_set_window(WindowHandleAlign)dev_display(Image)get_metrology_object_result_contour(MeasuredLines,MetrologyHandle,'all','all',1.5)gen_cross_contour_xld(RefPoints,RowRef,ColRef,16,rad(45))dev_set_line_width(2)dev_set_color('green')dev_display(MeasuredLines)dev_set_color('blue')dev_display(RefPoints)dev_set_line_width(1)disp_message(WindowHandleAlign,['Lines measured in the reference image','and reference points on the lines'],'window',12,12,'black','true')disp_continue_message(WindowHandle,'black','true')stop()**Create the variation model.create_variation_model(Width,Height,'byte','standard',VariationModelID)forI:=1to15by1read_image(Image,'pen/pen-'+I$'02d')*Apply the metrology model to the current image and read out the line segment*coordinates.apply_metrology_model(Image,MetrologyHandle)get_metrology_object_result(MetrologyHandle,'all','all','result_type','row_begin',RowBegin)get_metrology_object_result(MetrologyHandle,'all','all','result_type','column_begin',ColBegin)get_metrology_object_result(MetrologyHandle,'all','all','result_type','row_end',RowEnd)get_metrology_object_result(MetrologyHandle,'all','all','result_type','column_end',ColEnd)*Determine a rigid transformation based on the point-to-line correspondences*from the reference points to the extracted lines.Note that this determines*a transformation from the reference points to the lines in the current image.*Therefore,we must invert this transformation to obtain the transformation*from the current image to the rerefence image.point_line_to_hom_mat2d('rigid',RowRef+0.5,ColRef+0.5,RowBegin+0.5,ColBegin+0.5,RowEnd+0.5,ColEnd+0.5,HomMat2D)hom_mat2d_invert(HomMat2D,HomMat2DInvert)affine_trans_image(Image,ImageTrans,HomMat2DInvert,'constant','false')*Train the variation model with the transformed,i.e.,aligned image.train_variation_model(ImageTrans,VariationModelID)dev_set_window(WindowHandleAlign)dev_display(Image)get_metrology_object_result_contour(MeasuredLines,MetrologyHandle,'all','all',1.5)dev_set_line_width(2)dev_set_color('green')dev_display(MeasuredLines)dev_set_color('blue')dev_display(RefPoints)dev_set_line_width(1)disp_message(WindowHandleAlign,['Lines measured in the current','image and reference points'],'window',12,12,'black','true')dev_set_window(WindowHandle)dev_clear_window()dev_display(ImageTrans)affine_trans_contour_xld(MeasuredLines,MeasuredLinesTrans,HomMat2DInvert)dev_set_line_width(2)dev_set_color('green')dev_display(MeasuredLinesTrans)dev_set_color('blue')dev_display(RefPoints)dev_set_line_width(1)disp_message(WindowHandle,['Measured lines transformed to the','reference image pose and reference points'],'window',12,12,'black','true')disp_continue_message(WindowHandle,'black','true')stop()endforget_variation_model(MeanImage,VarImage,VariationModelID)prepare_variation_model(VariationModelID,20,3)*We can now free the training data to save some memory.clear_train_data_variation_model(VariationModelID)dev_set_window(WindowHandleAlign)dev_display(MeanImage)disp_message(WindowHandleAlign,'Reference image','window',12,12,'black','true')dev_set_window(WindowHandle)dev_display(VarImage)disp_message(WindowHandle,'Variation image','window',12,12,'black','true')disp_continue_message(WindowHandle,'black','true')stop()**Check and classify images of correct and incorrect prints.NumImages:=30forI:=1to30by1read_image(Image,'pen/pen-'+I$'02d')apply_metrology_model(Image,MetrologyHandle)get_metrology_object_result(MetrologyHandle,'all','all','result_type','row_begin',RowBegin)get_metrology_object_result(MetrologyHandle,'all','all','result_type','column_begin',ColBegin)get_metrology_object_result(MetrologyHandle,'all','all','result_type','row_end',RowEnd)get_metrology_object_result(MetrologyHandle,'all','all','result_type','column_end',ColEnd)point_line_to_hom_mat2d('rigid',RowRef+0.5,ColRef+0.5,RowBegin+0.5,ColBegin+0.5,RowEnd+0.5,ColEnd+0.5,HomMat2D)hom_mat2d_invert(HomMat2D,HomMat2DInvert)affine_trans_image(Image,ImageTrans,HomMat2DInvert,'constant','false')reduce_domain(ImageTrans,RegionROI,ImageReduced)compare_variation_model(ImageReduced,RegionDiff,VariationModelID)connection(RegionDiff,ConnectedRegions)select_shape(ConnectedRegions,RegionsError,'area','and',20,1000000)count_obj(RegionsError,NumError)dev_set_window(WindowHandle)dev_clear_window()dev_display(ImageTrans)dev_set_color('red')dev_set_draw('margin')dev_display(RegionsError)disp_message(WindowHandle,'Aligned image','window',12,12,'black','true')if(NumError==0)disp_message(WindowHandle,'Print OK','window',12,300,'green','false')elsedisp_message(WindowHandle,'Print not OK','window',12,300,'red','false')endifdev_set_window(WindowHandleAlign)dev_display(Image)get_metrology_object_result_contour(MeasuredLines,MetrologyHandle,'all','all',1.5)dev_set_line_width(2)dev_set_color('green')dev_display(MeasuredLines)dev_set_color('blue')dev_display(RefPoints)dev_set_line_width(1)disp_message(WindowHandleAlign,['Lines measured in the current','image and reference points'],'window',12,12,'black','true')if(I<NumImages)disp_continue_message(WindowHandle,'black','true')stop()endif endforclear_variation_model(VariationModelID)clear_metrology_model(MetrologyHandle)八、总结
关键点回顾
get_metrology_object_result是2D计量模块获取最终拟合测量结果的核心算子,支持读取几何参数、拟合分数、所用边缘点;GenParamName和GenParamValue的组合决定结果类型,all_param可批量返回目标的所有几何参数,且坐标类型(像素/公制)取决于相机参数是否设置;- 结果顺序遵循“先对象内实例,后多个对象”的规则,角度方向可通过
angle_direction控制(默认逆时针,单位弧度)。