如果被测量的对象可以被直线、圆、椭圆、矩形表示,并且拥有已知的无限靠近这些被测量对象的边缘或其他参数(位置、方向、尺寸等),在这种情况下使用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')
原始图像,以及检测结果图像显示:
这里其实可以结合一维测量中的gen_measure_rectangle2和measure_pos算子来进行理解。下面是我用一维检测中的方法实现的直线和圆的检测代码可供参考:
step1: 创建2dMetrology计量模型,并指定待测量图像的尺寸;
step2: 将计量对象的相关数据添加到计量模型中;
step3: 检查或可视化添加到计量模型中的几何对象的contour;以及查看创建的测量rectangle2的contour;
step4(可选): 使用set_metrology_object_param修改添加到模型中对象的参数;
step5: 在使用过定义的模型后,想要直接继续使用该模型,可以通过使用align_metrology_model()将创建的模型对齐到新的检测目标对象,该算子的相关对齐参数,一般是使用基于shape的模板匹配方法所得,当然也可以使用其他检测方法。
step6: 实施模型的测量
step7: 若要反复使用定义好的model,最好的方式是将定义好的model进行保存等操作。
step8:(对step5中内容的补充) 若要实现将在一个图像中定义的计量模型应用到其他的图像,需要使用align_metrology_model(), 其实现核心就是将生成检测矩形的参考点参数进行的更改,具体的方法如下所示:
1. 获取新图像中待测量对象的位置:
1.1. 使用基于shape-based匹配方法;
1.2. 使用区域分割的方法;
1.3. 使用点之间的对应关系对定义的模型进行仿射变换();
2. 获取关键参数,并使用set_metrology_model_param()将参数写入。并应用计量模型检测算子。
Note: 下面是对step8中重新利用计量模型的简单案例:
在两张不同的图像中使用同一个计量模型进行测量。
// 案例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)