【Halcon回顾之2D Metrology】

Halcon系统回顾之2D Metrology

  • 2D Metrology的适用场景
  • 文章的展开逻辑
  • 官方案例
    • 代码关键图像结果展示
  • 上述案例中核心算子的理解
  • 2D Metrology通用方案与测试代码

2D Metrology的适用场景

如果被测量的对象可以被直线、圆、椭圆、矩形表示,并且拥有已知的无限靠近这些被测量对象的边缘或其他参数(位置、方向、尺寸等),在这种情况下使用2D计量去提取被测量对象的相关参数将是可靠且有效的。

文章的展开逻辑

以一个具体的官方案例进行展开,先建立对2D Metrology的一个整体认识。然后再去拓展更多的相关算法。最后针对2D计量问题建立一个通用的解决方案流程。(自己使用1D检测算子实现直线和圆的检测------可以参考另一篇1D测量中有实现代码,如果感兴趣完全也可以实现各种几何形状的检测)

官方案例

* 实现圆和矩形的测量

* step1:图像显示初始化
dev_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')
 
* step2:定义近似的位置和测量圆圈的公差,其实就是手动设置圆存在的中心点位置
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

* step3:定义近似的位置和测量矩形的公差,设置矩形的轮廓区域
RectangleInitRow := [410,410]
RectangleInitColumn := [215,562]
RectangleInitPhi := [0,0]
RectangleInitLength1 := [85,85]
RectangleInitLength2 := [88,88]
RectangleTolerance := 10

* step4:创建测量模型(数据结构)
create_metrology_model (MetrologyHandle)

* step5:设置测量数据结构的待检测图像的宽高(提升检测时间).
set_metrology_model_image_size (MetrologyHandle, Width, Height)

* step6:将上面的矩形对象添加到测量模型中
add_metrology_object_rectangle2_measure (MetrologyHandle, RectangleInitRow, RectangleInitColumn, RectangleInitPhi, RectangleInitLength1, RectangleInitLength2, RectangleTolerance, 5, .5, 1, [], [], MetrologyRectangleIndices)

*step7:将上面的圆形对象添加到测量模型中
add_metrology_object_circle_measure (MetrologyHandle, CircleInitRow, CircleInitColumn, CircleInitRadius, CircleRadiusTolerance, 5, 1.5, 2, [], [], MetrologyCircleIndices)

*step8:设置测量模型对象的检测对象相关参数(每个计量对象可以测量一个以上的圆/矩形/线/椭圆)
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)

*step9: 实施测量
apply_metrology_model (Image, MetrologyHandle)

*step10: 获取测量结果
get_metrology_object_result (MetrologyHandle, MetrologyRectangleIndices, 'all', 'result_type', 'all_param', RectangleParameter)

 1. 这里要知道RectangleParameter检测结果参数的数据结构信息
Sequence := [0:5:|RectangleParameter| - 1]
RectangleRow := RectangleParameter[Sequence]
RectangleColumn := RectangleParameter[Sequence + 1]
RectanglePhi := RectangleParameter[Sequence + 2]
RectangleLength1 := RectangleParameter[Sequence + 3]
RectangleLength2 := RectangleParameter[Sequence + 4]

 2. 获取圆形检测结果
get_metrology_object_result (MetrologyHandle, MetrologyCircleIndices, 'all', 'result_type', 'all_param', CircleParameter)
 3. 提取检测结果更加详细的信息
Sequence := [0:3:|CircleParameter| - 1]
CircleRow := CircleParameter[Sequence]
CircleColumn := CircleParameter[Sequence + 1]
CircleRadius := CircleParameter[Sequence + 2]
 4. 
 5. 结果展示
 6. 
 7. 获取测量conturs
get_metrology_object_result_contour (Contours, MetrologyHandle, 'all', 'all', 1.5)
 8. 获取到检测区域的conturs,以及轮廓坐标,并根据这些坐标去拟合成圆或矩形
get_metrology_object_measures (Contour, MetrologyHandle, 'all', 'all', Row1, Column1)
gen_cross_contour_xld (Cross, Row1, Column1, 6, 0.785398)

 9. 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')

代码关键图像结果展示

原始图像,以及检测结果图像显示:
【Halcon回顾之2D Metrology】_第1张图片【Halcon回顾之2D Metrology】_第2张图片
【Halcon回顾之2D Metrology】_第3张图片
这里其实可以结合一维测量中的gen_measure_rectangle2和measure_pos算子来进行理解。下面是我用一维检测中的方法实现的直线和圆的检测代码可供参考:

上述案例中核心算子的理解

  • create_metrology_model(MetrologHandle) 创建2D计量模型,该模型对应的数据结构用于存储所有的几何对象,以及所有测量所需的参数和最终测量结果数据。
  • get_metrology_object_result(MetrologyHandle,Index,Instance,GenParamName,GenParamValue,Parameter) 获取测量结果----侧面窥探计量模型的数据结构:
    1. GenParamName:
    2. GenParamValue:

2D Metrology通用方案与测试代码

step1: 创建2dMetrology计量模型,并指定待测量图像的尺寸;

  • 使用create_metrology_model创建计量模型;(该模型将会存储被测量对象的所有相关参数)
  • 使用set_metrology_model_image_size设置计量模型数据结构中的图像尺寸;

step2: 将计量对象的相关数据添加到计量模型中;

  • add_metrology_object_circle_measure()添加圆对象到计量模型中;
  • add_metrology_object_ellipse_measure()添加椭圆对象到计量模型中;
  • add_metrology_object_rectangle2_measure()添加矩形对象到计量模型中;
  • add_metrology_object_line_measure()添加线对象到模型中;
  • 当然也可以使用add_metrology_object_generic()直接配置任意形状的对象类型到计量模型中;

step3: 检查或可视化添加到计量模型中的几何对象的contour;以及查看创建的测量rectangle2的contour;

  • get_metrology_object_model_contour(); 获取添加到模型中的对象XLD轮廓
  • get_metrology_object_measures(); 获取生成的用于测量的矩形XLD轮廓;

step4(可选): 使用set_metrology_object_param修改添加到模型中对象的参数;

step5: 在使用过定义的模型后,想要直接继续使用该模型,可以通过使用align_metrology_model()将创建的模型对齐到新的检测目标对象,该算子的相关对齐参数,一般是使用基于shape的模板匹配方法所得,当然也可以使用其他检测方法。

step6: 实施模型的测量

  • 使用apply_metrology_model()应用创建的测量模型,其实这里的内部机制是使用了1D检测中的 measure_pos()或fuzzy_measure_pos()检测算子去检测边缘。
  • 获取测量结果:
    1. get_metrology_object_result可以返回拟合后的集合对象的相关参数,也可以只返回拟合的边缘和振幅。
    2. get_metrology_object_measures()可以获取所有边缘的行列坐标;
    3. get_metrology_object_result_contour()可以可视化拟合后的目标集合对象的轮廓,并且可以获取这些拟合几何形状的XLD轮廓。

step7: 若要反复使用定义好的model,最好的方式是将定义好的model进行保存等操作。

step8:(对step5中内容的补充) 若要实现将在一个图像中定义的计量模型应用到其他的图像,需要使用align_metrology_model(), 其实现核心就是将生成检测矩形的参考点参数进行的更改,具体的方法如下所示:
1. 获取新图像中待测量对象的位置:
1.1. 使用基于shape-based匹配方法;
1.2. 使用区域分割的方法;
1.3. 使用点之间的对应关系对定义的模型进行仿射变换();
2. 获取关键参数,并使用set_metrology_model_param()将参数写入。并应用计量模型检测算子。

Note: 下面是对step8中重新利用计量模型的简单案例:
在两张不同的图像中使用同一个计量模型进行测量。
【Halcon回顾之2D Metrology】_第4张图片
【Halcon回顾之2D Metrology】_第5张图片

// 案例1: 使用基于模板匹配的方式重用计量模型
read_image (Image, 'C:/Users/620H/Desktop/博客代码/3.jpg')
rgb1_to_gray (Image, Image3)

dev_get_window (WindowHandle)
dev_display (Image3)

* step1: 创建测量对象的逼近轮廓
draw_circle (WindowHandle, Row, Column, Radius)
gen_circle (Circle, Row, Column, Radius)

* step2: 创建2D计量模型
create_metrology_model (MetrologyHandle)
get_image_size (Image3, Width, Height)
set_metrology_model_image_size (MetrologyHandle, Width, Height)

* step3: 查验添加到计量模型中的预检测轮廓
add_metrology_object_circle_measure (MetrologyHandle, Row, Column, Radius, 20, 5, 1, 30, [], [], Index)

get_metrology_object_model_contour (Contour, MetrologyHandle, 0, 1.5)   // 传入到计量模型中的集合轮廓
get_metrology_object_measures (Contours, MetrologyHandle, 'all', 'all', Row1, Column1)   // 测量矩形轮廓

* step4: 应用计量模型
apply_metrology_model (Image3, MetrologyHandle)

* step6: 查看测量结果
get_metrology_object_result (MetrologyHandle, 0, 'all', 'result_type', 'all_param', Parameter)   //Parameter:中心点和半径
gen_cross_contour_xld (Cross, Parameter[0], Parameter[1], 16, 0.785398)

get_metrology_object_result_contour (Contour1, MetrologyHandle, 0, 'all', 1.5)    // 获取的最终拟合到的轮廓


* spart1: 使用模板匹配方式重用上面计量模型

* 7.1: 获取模板图像
set_system ('border_shape_models', 'false')

dev_clear_window ()
dev_display (Image3)

draw_circle (WindowHandle, Row3, Column3, Radius1)
gen_circle (ModelRegion, Row3, Column3, Radius1)
reduce_domain (Image3, ModelRegion, TemplateImage)

* 7.2: 创建模板
create_shape_model (TemplateImage, 5,rad(-45), rad(180), rad(0.7394), ['none','no_pregeneration'], 'use_polarity', [21,47,4], 8, ModelID)
* 获取创建模板的轮廓

* 将模板的中心点作为计量生成检测矩形区域的参考中心点
area_center (ModelRegion, Area, Row2, Column2)
set_metrology_model_param (MetrologyHandle, 'reference_system', [Row2,Column2,0])


get_shape_model_contours (ModelContours, ModelID, 1)

* 读取待检测图像
read_image (Image5, 'C:/Users/620H/Desktop/博客代码/5.jpg')
rgb1_to_gray (Image5, GrayImage)
dev_display (GrayImage)

* 7.3: 搜索目标
find_shape_model (GrayImage, ModelID, rad(-45), rad(180), 0.8, 0, 0.5, 'least_squares', [5,1], 1, Row, Column, Angle, Score)

* 如果检测到了才执行,只选匹配度最高的目标
if(|Score| > 0)
     tuple_sort_index (Row, Indices)
     tuple_inverse (Indices, Inverted)
     index_max := Inverted[0]
     
     *7.4 生成仿射变换矩阵
     hom_mat2d_identity (HomMat2D) 
     hom_mat2d_rotate (HomMat2D, Angle[index_max], 0, 0, HomMat2D)
     hom_mat2d_translate (HomMat2D, Row[index_max], Column[index_max], HomMat2D)
     affine_trans_contour_xld (ModelContours, TransContours, HomMat2D)
     
     dev_set_color ('green')
     dev_display (TransContours)
     
     * 7.5 将计量模型生成测量矩形的参考点替换为新检测目标的中心点
     align_metrology_model (MetrologyHandle,Row[index_max], Column[index_max], Angle[index_max])
    
     * 检查传入的轮廓是否合理
     get_metrology_object_model_contour (Contour3, MetrologyHandle, 0, 1.5)
     
     get_metrology_object_measures (Contours1, MetrologyHandle, 'all', 'all', Row4, Column4)
     
     * 7.6 应用计量模型到新的图片上
     apply_metrology_model (GrayImage, MetrologyHandle)
     get_metrology_object_result_contour (Contour2, MetrologyHandle, 0, 'all', 1.5)    // 获取的最终拟合到的轮廓
endif
clear_shape_model (ModelID)

你可能感兴趣的:(halcon,机器视觉,计算机视觉,图像处理)