Detailed explanation of Halcon routines (matching measurement method based on caliper tools)-measure_stamping_part.hdev

Preface

1Introduction to caliper tools

The Metrology method in Halcon is a caliper tool, which can be used to fit lines and circles. This method is very convenient for image size measurement where the target is more obvious than the background. There is no need to use blobs for edge extraction, etc., but the shortcomings are also obvious. , The relative position of the target needs to be basically unchanged.
Insert picture description here

2Matching method concept

There are three matching methods provided in the HDevelop development environment, namely Component-Based, Gray-Value-Based, and Shape-Based, which are component-based matching, gray value-based matching and shape-based matching. The examples used in this article The process method is shape-based matching.

Routine detailed explanation

**模型的名字为基于形状的匹配方法
AlignmentMode := 'shape-based matching'
* AlignmentMode := 'region processing'(区域)
* AlignmentMode := 'rigid transformation'(刚性变换)
* 
* 初始化视图
dev_update_off ()
dev_close_window ()
dev_set_draw ('margin')
gen_empty_obj (EmptyObject)
read_image (Image, 'metal-parts/circle_plate_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

Insert picture description here

* Part I:
* 
* 初始化卡尺模型
* 定义相机参数
gen_cam_par_area_scan_division (0.0128649, -661.434, 5.30004e-006, 5.3e-006, 620.043, 497.402, Width, Height, CameraParam)
* 测量平面的位姿是通过标定板标定得到的,懂标定的自然懂。
MeasurementPlane := [0.00940956,-0.00481017,0.29128,0.478648,359.65,0.785,0]
* 根据零件的高度和校准板的高度调整测量平面的位姿
CalibPlateThickness := 0.006
PartHeight := 0.005
AdjustThickness := CalibPlateThickness - PartHeight
set_origin_pose (MeasurementPlane, 0, 0, AdjustThickness, MeasurementPlaneAdjusted)
* 
* 创建标定模型并准备标定测量
create_metrology_model (MetrologyHandle)
* 提前设置图像大小,以加快第一次调用apply_metrology_model的速度
set_metrology_model_image_size (MetrologyHandle, Width, Height)
* 在卡尺模型里设置相机参数
set_metrology_model_param (MetrologyHandle, 'camera_param', CameraParam)
* 设置被测对象的位姿
set_metrology_model_param (MetrologyHandle, 'plane_pose', MeasurementPlaneAdjusted)
* 
* Add the objects to be measured to the metrology model
* 
* 添加圆的参数(由上图可知有四个完整的圆):行列坐标,半径
CircleParam := [354,274,53]
CircleParam := [CircleParam,350,519,53]
CircleParam := [CircleParam,345,764,52]
CircleParam := [CircleParam,596,523,53]
add_metrology_object_generic (MetrologyHandle, 'circle', CircleParam, 20, 5, 1, 30, [], [], CircleIndices1)
* 
* 添加两个残缺的圆。
CircleParam1 := [583,1010,79]
CircleParam2 := [336,1005,77]
*角度不同,故写了两次
add_metrology_object_generic (MetrologyHandle, 'circle', CircleParam1, 20, 5, 1, 30, ['start_phi','end_phi'], [0,rad(185)], CircleIndices2)
add_metrology_object_generic (MetrologyHandle, 'circle', CircleParam2, 20, 5, 1, 30, ['start_phi','end_phi'], [rad(45),rad(185)], Index3)
CircleIndices2 := [CircleIndices2,Index3]
* 
* 添加一个矩形
RectangleParam := [599,279,rad(90),62,51]
add_metrology_object_generic (MetrologyHandle, 'rectangle2', RectangleParam, 20, 5, 1, 30, [], [], RectIndices)

* 添加两条线(边界线)
Line1 := [143,1122,709,1132]
Line2 := [151,153,136,1115]
add_metrology_object_generic (MetrologyHandle, 'line', [Line1,Line2], 20, 5, 1, 30, [], [], LineIndices)
* 检查已添加到计量模型中的形状
get_metrology_object_model_contour (ModelContour, MetrologyHandle, 'all', 1.5)
get_metrology_object_measures (MeasureContour, MetrologyHandle, 'all', 'all', Row, Column)
Message := 'This example shows how to measure geometric shapes using a'
Message[1] := 'metrology model. As preparation, their roughly known '
Message[2] := 'dimensions and tolerances are specified by the user.'
show_contours (Image, ModelContour, MeasureContour, EmptyObject, WindowHandle, Message)
stop ()

Insert picture description here

* Part 2:
* 
* 准备匹配
* 
* a) Shape-based matching
if (AlignmentMode == 'shape-based matching')
    dev_set_part (-Height / 2 - 100, -Width / 2, 1.5 * Height - 100, 1.5 * Width)
    * 
    * 创建用于图像中计量模型匹配的形状模型,其中对象的位置和方向与用于创建模型的图像中对象的位置和方向不同。
    * 得到当前halcon系统的参数值
    get_system ('border_shape_models', BorderShapeModel)
    set_system ('border_shape_models', 'true')
    *阈值处理并截取区域
    threshold (Image, Region, 0, 50)
    dilation_rectangle1 (Region, ModelRegion, 5, 5)
    reduce_domain (Image, ModelRegion, ImageReduced)
    *创建用于匹配的模型:参数(Template : : 金字塔级的数量, 起始角度, 角度范围, 角度的步长,优化的类型, 匹配度规, 阈值, 目标最小对比值 : ModelID)
    create_shape_model (ImageReduced, 6, 0, rad(360), 'auto', 'auto', 'use_polarity', 'auto', 20, ShapeModelID)
    *将模型的原点设置为输入区域的中心
    area_center (ModelRegion, Area, RowModel, ColumnModel)
    *得到形状模型的轮廓
    get_shape_model_contours (ShapeModelContours, ShapeModelID, 1)
    Message := 'A shape model will be used for the alignment of the metrology'
    Message[1] := 'model. The contours of the shape model (white) and of the'
    Message[2] := 'metrology model (blue) are shown.'
    show_contours (Image, ModelContour, EmptyObject, ShapeModelContours, WindowHandle, Message)
    * 
    * 更改定义卡尺模型的参考系统,使之与形状模型所使用的对应。
    set_metrology_model_param (MetrologyHandle, 'reference_system', [RowModel,ColumnModel,0])
    *得到卡尺模型的轮廓,参数:(模型轮廓,句柄,卡尺测量对象的索引,相邻两个轮廓点的距离
    get_metrology_object_model_contour (ModelContour, MetrologyHandle, 'all', 1.5)
    Message := 'To prepare the alignment, the origin of the shape model'
    Message[1] := 'is set as the reference system of the metrology model.'
    show_contours (Image, ModelContour, EmptyObject, ShapeModelContours, WindowHandle, Message)
    stop ()
    dev_set_part (0, 0, Height - 1, Width - 1)
endif
* 

Insert picture description here
*The other two matching models: region-based and affine transformation.

* b) Region processing
if (AlignmentMode == 'region processing')
    * Determine reference position and orientation
    threshold (Image, Region, 0, 50)
    fill_up (Region, RegionFillUp)
    difference (RegionFillUp, Region, OriginalRegion)
    area_center (OriginalRegion, Area, RowOrig, ColumnOrig)
    orientation_region (OriginalRegion, AngleOrig)
    * Change the reference system of the metrology model
    set_metrology_model_param (MetrologyHandle, 'reference_system', [RowOrig,ColumnOrig,AngleOrig])
endif
* 
* c) Rigid transformation
if (AlignmentMode == 'rigid transformation')
    * Reference points:
    extract_reference_points (Image, RowReference, ColumnReference)
    gen_cross_contour_xld (ReferencePoints, RowReference, ColumnReference, 15, 0.785398)
    dev_display (Image)
    dev_set_color ('white')
    dev_display (ReferencePoints)
    Message := 'To prepare the alignment, reference points are extracted.'
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    disp_message (WindowHandle, [1:4], 'image', RowReference, ColumnReference, 'black', 'true')
    stop ()
endif
* 
* 线上阶段
for I := 2 to 5 by 1
    read_image (CurrentImage, 'metal-parts/circle_plate_' + I$'02d')
    dev_set_line_width (1)
    dev_display (CurrentImage)
    * 
    * a) Shape-based matching
    if (AlignmentMode == 'shape-based matching')
        * 
        * 测量物体的位置和方向,使用find_shape_model算子。
        * 参数:(测试图,句柄,搜索角度,范围,模型实例的最小分数,模型数量,最大重叠度,亚像素精度,金字塔层数,
        * 搜索贪婪度(这个值在很大程度上影响着搜索速度,若为0,则为启发式搜索,若为1,则为不安全搜索),模型的行坐标,列坐标,角度,分数)
        find_shape_model (CurrentImage, ShapeModelID, 0, rad(360), 0.5, 1, 0, 'least_squares', 5, 0.9, RowAlign, ColumnAlign, AngleAlign, Score)
        dev_display_shape_matching_results (ShapeModelID, 'white', RowAlign, ColumnAlign, AngleAlign, 1, 1, 0)
    endif
    * 
    * b) Region processing
    if (AlignmentMode == 'region processing')
        * Determine the current position and orientation
        threshold (CurrentImage, Region, 0, 50)
        fill_up (Region, RegionFillUp)
        difference (RegionFillUp, Region, CurrentRegion)
        area_center (CurrentRegion, Area, RowAlign, ColumnAlign)
        orientation_region (CurrentRegion, AngleAlign)
    endif
    * 
    * c) Rigid transformation
    if (AlignmentMode == 'rigid transformation')
        * Referenzpunkte:
        extract_reference_points (CurrentImage, RowExtracted, ColumnExtracted)
        gen_cross_contour_xld (ExtractedPoints, RowExtracted, ColumnExtracted, 15, 0.785398)
        dev_display (CurrentImage)
        dev_set_color ('white')
        dev_display (ExtractedPoints)

        disp_message (WindowHandle, [1:4], 'image', RowExtracted, ColumnExtracted, 'black', 'true')
        vector_to_rigid (RowReference, ColumnReference, RowExtracted, ColumnExtracted, HomMat2D)
        hom_mat2d_to_affine_par (HomMat2D, Sx, Sy, AngleAlign, Theta, RowAlign, ColumnAlign)
    endif
    * 
    * 使用计算的位置和方向将计量模型与当前发生的事件对齐
    align_metrology_model (MetrologyHandle, RowAlign, ColumnAlign, AngleAlign)
    * 展示匹配效果
    if (I <= 2)
    **展示提取的轮廓
        get_metrology_object_model_contour (ModelContour, MetrologyHandle, 'all', 1.5)
        dev_set_color ('blue')
        dev_set_line_width (2)
        dev_display (ModelContour)
        Message := 'In each image, the object is matched and aligned'
        Message[1] := 'before the metrology measurement.'
        disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
    * 
    *在一次调用中对所有计量对象执行测量
    apply_metrology_model (CurrentImage, MetrologyHandle)
    * 获取测量区域以进行可视化
    get_metrology_object_measures (Contour, MetrologyHandle, 'all', 'all', Row, Column)
    * 获取用于拟合几何形状的边缘点
    get_metrology_object_result (MetrologyHandle, 'all', 'all', 'used_edges', 'row', UsedRow)
    get_metrology_object_result (MetrologyHandle, 'all', 'all', 'used_edges', 'column', UsedColumn)
    gen_cross_contour_xld (UsedEdges, UsedRow, UsedColumn, 10, rad(45))
    * 
    * 获取测量结果
    * 由于设置了摄像机参数,所有结果都以相对于测量平面所定义的坐标系的度量坐标给出
    * 
    * 得到所有的轮廓目标
    get_metrology_object_result_contour (ResultContours, MetrologyHandle, 'all', 'all', 1.5)
    * 提取小圆的半径
    get_metrology_object_result (MetrologyHandle, CircleIndices1, 'all', 'result_type', 'radius', RadiusC1)
    * 提取较大的不完整圆的半径
    get_metrology_object_result (MetrologyHandle, CircleIndices2, 'all', 'result_type', 'radius', RadiusC2)
    * 提取矩形边的长度
    get_metrology_object_result (MetrologyHandle, RectIndices, 'all', 'result_type', 'length1', Length1R)
    get_metrology_object_result (MetrologyHandle, RectIndices, 'all', 'result_type', 'length2', Length2R)
    * 获取每条测量线的起点和终点
    get_metrology_object_result (MetrologyHandle, LineIndices[0], 'all', 'result_type', 'all_param', ParamLine1)
    get_metrology_object_result (MetrologyHandle, LineIndices[1], 'all', 'result_type', 'all_param', ParamLine2)
    * Display the results
    dev_display (CurrentImage)
    dev_set_line_width (1)
    dev_set_color ('light gray')
    dev_display (Contour)
    dev_set_color ('green')
    dev_set_line_width (2)
    dev_display (ResultContours)
    dev_set_line_width (1)
    dev_set_color ('white')
    dev_display (UsedEdges)
    * 
    * 显示圆心处每个圆的半径
    * 获取圆心的度量坐标
    get_metrology_object_result (MetrologyHandle, CircleIndices1, 'all', 'result_type', 'x', XC1)
    get_metrology_object_result (MetrologyHandle, CircleIndices1, 'all', 'result_type', 'y', YC1)
    * 将圆心的度量坐标投影到图像中,得到圆心的图像坐标
    project_xy_to_image (XC1, YC1, MeasurementPlaneAdjusted, CameraParam, Row1, Column1)
    get_metrology_object_result (MetrologyHandle, CircleIndices2, 'all', 'result_type', 'x', XC2)
    get_metrology_object_result (MetrologyHandle, CircleIndices2, 'all', 'result_type', 'y', YC2)
    project_xy_to_image (XC2, YC2, MeasurementPlaneAdjusted, CameraParam, Row2, Column2)
    disp_message (WindowHandle, 'r=' + (RadiusC1 * 1000)$'.2f', 'image', Row1, Column1 - 80, 'black', 'true')
    disp_message (WindowHandle, 'r=' + (RadiusC2 * 1000)$'.2f', 'image', Row2, Column2 - 80, 'black', 'true')
    get_metrology_object_result (MetrologyHandle, RectIndices, 'all', 'result_type', 'x', XRectangle)
    get_metrology_object_result (MetrologyHandle, RectIndices, 'all', 'result_type', 'y', YRectangle)
    project_xy_to_image (XRectangle, YRectangle, MeasurementPlaneAdjusted, CameraParam, RowR, ColumnR)
    Area := Length1R * Length2R * 4 * 1000 * 1000
    disp_message (WindowHandle, 'area=' + Area$'.2f', 'image', RowR, ColumnR - 120, 'black', 'true')
    Message := 'Measured metric results after alignment (r in mm, area in mm^2):'
    * 
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    if (I < 5)
        disp_continue_message (WindowHandle, 'black', 'true')
    endif
    stop ()
    
endfor
if (AlignmentMode == 'shape-based matching')
    set_system ('border_shape_models', BorderShapeModel)
endif

to sum up

The use of the caliper tool in halcon is relatively simple, based on the matching caliper measurement is divided into the following steps:

  1. Create a caliper model, add measurement item information, create_metrology_model, add_metrology_object_generic.
  2. Create a matching model for shape matching, create_shape_model.
  3. Use the matching model to match the actual image, find_shape_model
  4. 展示匹配结果,get_metrology_object_model_contour,apply_metrology_model,get_metrology_object_measures,get_metrology_object_result。

Guess you like

Origin blog.csdn.net/baidu_35536188/article/details/113725864