Halcon 模板匹配基于轮廓(形状)

2024-01-09 16:42:09

halcon 案例 基于缩放比

算子
创建匹配模板1.create_scaled_shape_model(Template : : NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Optimization, Metric, Contrast,MinContrast : ModelID)



示例:create_scaled_shape_model (ImageReduced1, 'auto', 0, rad(360), 'auto',  0.2,  1.5, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)

ImageReduced1(输入对象):输入图像对象

'auto'(输入控制参数1):默认自动获取

0(输入控制参数2):创建模板的起始角度(弧度)

rad(360) (输入控制参数3):创建模板的终止角度(弧度)

'auto'(输入控制参数4):默认自动获取

0.2(输入控制参数5):缩放最小比例

1.5(输入控制参数6):缩放最大比例

'auto'(输入控制参数7):默认自动获取

'auto'(输入控制参数8):默认自动获取

'use_polarity'(输入控制参数9):设置模板优化和模板创建方法

'auto'(输入控制参数10):默认自动获取

'auto'(输入控制参数11):默认自动获取

ModelID(输出控制参数):输出模板句柄

2.发现模板find_scaled_shape_model

算子:find_scaled_shape_model(Image : : ModelID, AngleStart, AngleExtent, ScaleMin, ScaleMax, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels, Greediness :Row, Column, Angle, Scale, Score)

示例:find_scaled_shape_model (Image, ModelID, 0, rad(360),  0.2, 1.9, 0.8, 4, 0.8, 'least_squares', 0, 0.9, Row, Column, Angle, Scale, Score)

Image(输入对象):输入需要找寻的图像

ModelID(输入控制参数1):输入模和句柄

0(输入控制参数2):找寻的起始角度

rad(360)(输入控制参数3):找寻的终止角度

0.2(输入控制参数4):找寻的最小缩放比

1.9(输入控制参数5):找寻的最大缩放比

0.8(输入控制参数6):最小匹配分数

4(输入控制参数7):找寻的最大个数

0.8(输入控制参数8):最大覆盖率还可以发现系数值

'least_squares'(输入控制参数9):计算精度的设置

0(输入控制参数10):搜索时金字塔的层数

0.9(输入控制参数11):贪婪度  一般设置为0.9 速度快 容易出现找不到的情况

Row(输出控制参数1):匹配位置的行坐标

Column(输出控制参数2):匹配位置的列坐标

Angle(输出控制参数3):匹配位置的角度

Scale(输出控制参数4):默认值Score(输出控制参数5):匹配位置的得分

3.获取模板的轮廓进行查看get_shape_model_contours

算子:get_shape_model_contours( : ModelContours : ModelID, Level : )

示例:get_shape_model_contours (ModelContours, ModelID, 1)

ModelContours(输出对象):输出模板轮廓

ModelID (输入控制参数):输入模板句柄

1(输入控制参数):输入显示数量

4. 显示找到的结果dev_display_shape_matching_results

算子:dev_display_shape_matching_results( : : ModelID, Color, Row, Column, Angle, ScaleR, ScaleC, Model : )

示例:dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, 1, 1, 0))

ModelID(输入控制参数1):输入模型的句柄

'red'(输入控制参数2):设定显示颜色

Row(输出控制参数3):输入显示的行坐标

Column(输入控制参数4):输入显示的列坐标

Angle(输入控制参数5):输入显示的角度

1(输入控制参数6):水平方向的缩放比例

1(输入控制参数7):垂直方向的缩放比例

0(输入控制参数8):找到的模型实例的索引

4. 显示找到的结果dev_display_shape_matching_results
  1. 清除句柄
算子:clear_shape_model( : : ModelID : )

示例:clear_shape_model(ModelID)
 ModelID(输入控制参数):输入模型句柄

在这里插入图片描述

预处理

* This example program shows how to find scaled and rotated shape models.
dev_update_pc ('off')
dev_update_window ('off')
dev_update_var ('off')
read_image (Image, 'green-dot')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_set_color ('red')
dev_display (Image)
threshold (Image, Region, 0, 128)
*形成单独的连通域
connection (Region, ConnectedRegions)
*选中面积大小
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10000, 20000)
*进行填充
fill_up (SelectedRegions, RegionFillUp)
*进行膨胀
dilation_circle (RegionFillUp, RegionDilation, 5.5)
*裁剪掉膨胀区域
reduce_domain (Image, RegionDilation, ImageReduced)

创建模板获取轮廓

*创建模板
create_scaled_shape_model (ImageReduced, 5, rad(-45), rad(90), 'auto', 0.8, 1.0, 'auto', 'none', 'ignore_global_polarity', 40, 10, ModelID)
*获取模板轮廓
get_shape_model_contours (Model, ModelID, 1)
*获取区域中心点
area_center (RegionFillUp, Area, RowRef, ColumnRef)
*仿射运算
vector_angle_to_rigid (0, 0, 0, RowRef, ColumnRef, 0, HomMat2D)
affine_trans_contour_xld (Model, ModelTrans, HomMat2D)
dev_display (Image)
dev_display (ModelTrans)
read_image (ImageSearch, 'green-dots')
dev_display (ImageSearch)

寻找模板显示

*寻找模板
find_scaled_shape_model (ImageSearch, ModelID, rad(-45), rad(90), 0.8, 1.0, 0.5, 0, 0.5, 'least_squares', 5, 0.8, Row, Column, Angle, Scale, Score)
for I := 0 to |Score| - 1 by 1
    *用于显示
    *初始化一个空的仿射变换矩阵
    hom_mat2d_identity (HomMat2DIdentity)
    *平移
    hom_mat2d_translate (HomMat2DIdentity, Row[I], Column[I], HomMat2DTranslate)
    *旋转
    hom_mat2d_rotate (HomMat2DTranslate, Angle[I], Row[I], Column[I], HomMat2DRotate)
    *缩放
    hom_mat2d_scale (HomMat2DRotate, Scale[I], Scale[I], Row[I], Column[I], HomMat2DScale)
    *对XLD轮廓(contour)进行一个任意二维仿射变换
    affine_trans_contour_xld (Model, ModelTrans, HomMat2DScale)
    dev_display (ModelTrans)
endfor

在这里插入图片描述

halcon 案例 测单个剃须刀片

在这里插入图片描述

图片的显示设置

dev_update_window ('off')
* image acquisition and window size
read_image (ModelImage, 'razors1')
*返回指向图像Image的第一个通道的指针
get_image_pointer1 (ModelImage, Pointer, Type, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'white', WindowHandle)
*修改要显示的图像部分
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (ModelImage)
* colors and other settings for the visualization
dev_set_color ('cyan')
dev_set_draw ('margin')
dev_set_line_width (2)

获取上顶部和下底部的位置

Row1 := 46
Column1 := 57
Row2 := 79
Column2 := 94
gen_rectangle1 (ROIPart1, Row1, Column1, Row2, Column2)
gen_rectangle1 (ROIPart2, Row1 + 364, Column1 + 13, Row2 + 364, Column2 + 13)
union2 (ROIPart1, ROIPart2, ModelROI)
area_center (ModelROI, Area, CenterROIRow, CenterROIColumn)
dev_display (ModelImage)
dev_display (ModelROI)
stop ()

在这里插入图片描述

创建模型

 inspect_shape_model 和 create_shape_model 是 Halcon 中用于形状模型的函数,它们在形状匹配和检测中扮演不同的角色。

create_shape_model:
create_shape_model 用于创建一个形状模型,该模型将用于后续的形状匹配。在使用 create_shape_model 函数时,需要提供以下参数:

    模板图像:即作为形状模型的参考的模板图像。
    配置参数:用于指定形状模型的创建参数,如平移不变性、旋转不变性等。

函数会根据给定的模板图像和配置参数生成一个形状模型,该模型包含了模板图像的形状信息。

inspect_shape_model:
inspect_shape_model 用于检查已创建的形状模型,并获取有关模型参数的信息。通过使用 inspect_shape_model 函数,你可以获取形状模型的相关属性,如模型的分辨率、角度范围、平移范围等。

函数返回的信息可以帮助你理解形状模型的特性,并在后续形状匹配的过程中进行相应的调整和优化。

总结来说,create_shape_model 用于创建形状模型,而 inspect_shape_model 则用于检查已创建的形状模型并获得其属性信息。这两个函数通常一起使用,先通过 create_shape_model 创建模型,然后使用 inspect_shape_model 检查模型并对其进行调整。
inspect_shape_model(图像,得到金字塔图像,得到对应的区域,金字塔层数,对比度)
* -> create the model
reduce_domain (ModelImage, ModelROI, ImageROI)
*创建形状模型
create_shape_model (ImageROI, 4, 0, 0, 'auto', 'none', 'use_polarity', 30, 10, ModelID)
*创建形状模型的表示
inspect_shape_model (ImageROI, ShapeModelImage, ShapeModelRegion, 1, 30)
get_shape_model_contours (ShapeModel, ModelID, 1)
dev_clear_window ()
dev_set_color ('blue')
dev_display (ShapeModelRegion)
stop ()

在这里插入图片描述

获取竖直条

Rect1Row := 244
Rect1Col := 73
DistColRect1Rect2 := 17
Rect2Row := Rect1Row
Rect2Col := Rect1Col + DistColRect1Rect2
RectPhi := rad(90)
RectLength1 := 122
RectLength2 := 2
gen_rectangle2 (MeasureROI1, Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2)
gen_rectangle2 (MeasureROI2, Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2)
dev_display (ModelImage)
dev_set_color ('yellow')
dev_display (MeasureROI1)
dev_display (MeasureROI2)

在这里插入图片描述

将测量区域沿着 XLD 模型的方向进行平移,以便后续进行测量操作

* translate measurement ROIs to lie on XLD model (without clipping!)
*获取当前系统中用于裁剪图像的默认区域
get_system ('clip_region', OriginalClipRegion)
*设置当前系统中用于裁剪图像的默认区域为“false”,即不使用任何区域进行裁剪。
set_system ('clip_region', 'false')
*将区域移动到指定的位置
move_region (MeasureROI1, MeasureROI1Ref, -CenterROIRow, -CenterROIColumn)
move_region (MeasureROI2, MeasureROI2Ref, -CenterROIRow, -CenterROIColumn)
set_system ('clip_region', OriginalClipRegion)
DistRect1CenterRow := Rect1Row - CenterROIRow
DistRect1CenterCol := Rect1Col - CenterROIColumn
DistRect2CenterRow := Rect2Row - CenterROIRow
DistRect2CenterCol := Rect2Col - CenterROIColumn
if (USING_TRANSLATE_MEASURE != 0)
    * -> measure objects are created only once in advance and then translated later
    gen_measure_rectangle2 (Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1)
    gen_measure_rectangle2 (Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2)
endif
stop ()

在这里插入图片描述

查找到模板进行匹配显示,进行每一个锯齿进行匹配,先找头部,找到头部后找锯齿个数

* step 2: find the objects in another image
read_image (SearchImage, 'razors2')
dev_display (SearchImage)
find_shape_model (SearchImage, ModelID, 0, 0, 0.8, 0, 0.5, 'least_squares', 0, 0.7, RowCheck, ColumnCheck, AngleCheck, Score)
if (|Score| > 0)
    for i := 0 to |Score| - 1 by 1
        * step 3: determine the affine transformation
        vector_angle_to_rigid (0, 0, 0, RowCheck[i], ColumnCheck[i], AngleCheck[i], MovementOfObject)
        affine_trans_contour_xld (ShapeModel, ModelAtNewPosition, MovementOfObject)
        dev_display (ModelAtNewPosition)
        * step 4: measure width and distance of the teeth
        * -> display the moved ROIs
        affine_trans_region (MeasureROI1Ref, MeasureROI1AtNewPosition, MovementOfObject, 'constant')
        affine_trans_region (MeasureROI2Ref, MeasureROI2AtNewPosition, MovementOfObject, 'constant')
        dev_display (MeasureROI1AtNewPosition)
        dev_display (MeasureROI2AtNewPosition)
        affine_trans_pixel (MovementOfObject, DistRect1CenterRow, DistRect1CenterCol, Rect1RowCheck, Rect1ColCheck)
        affine_trans_pixel (MovementOfObject, DistRect2CenterRow, DistRect2CenterCol, Rect2RowCheck, Rect2ColCheck)
        if (USING_TRANSLATE_MEASURE != 0)
            * -> translate the already created measure objects
            translate_measure (MeasureHandle1, Rect1RowCheck, Rect1ColCheck)
            translate_measure (MeasureHandle2, Rect2RowCheck, Rect2ColCheck)
            measure_pairs (SearchImage, MeasureHandle1, 2, 25, 'negative', 'all', RowEdge11, ColEdge11, Amp11, RowEdge21, ColEdge21, Amp21, Width1, Distance1)
            measure_pairs (SearchImage, MeasureHandle2, 2, 25, 'negative', 'all', RowEdge12, ColEdge12, Amp12, RowEdge22, ColEdge22, Amp22, Width2, Distance2)
        else
            * -> create new measure objects and destroy them after the measurement
            RectPhiCheck := RectPhi + AngleCheck[i]
            gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, RectPhiCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1)
            gen_measure_rectangle2 (Rect2RowCheck, Rect2ColCheck, RectPhiCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2)
            * step 5: perform the measurement
            measure_pairs (SearchImage, MeasureHandle1, 2, 25, 'negative', 'all', RowEdge11, ColEdge11, Amp11, RowEdge21, ColEdge21, Amp21, Width1, Distance1)
            measure_pairs (SearchImage, MeasureHandle2, 2, 25, 'negative', 'all', RowEdge12, ColEdge12, Amp12, RowEdge22, ColEdge22, Amp22, Width2, Distance2)
            close_measure (MeasureHandle1)
            close_measure (MeasureHandle2)
        endif
        * step 6: check for too short or missing teeth
        NumberTeeth1 := |Width1|
        NumberTeeth2 := |Width2|
        dev_set_color ('red')
        if (NumberTeeth1 < 37)
            for j := 0 to NumberTeeth1 - 2 by 1
                if (Distance1[j] > 4.0)
                    RowFault := round(0.5 * (RowEdge11[j + 1] + RowEdge21[j]))
                    ColFault := round(0.5 * (ColEdge11[j + 1] + ColEdge21[j]))
                    disp_rectangle2 (WindowHandle, RowFault, ColFault, 0, 4, 4)
                    dev_open_window (0, Width + 20, 80, 80, 'black', WindowHandleZoom)
                    dev_set_part (RowFault - 10, ColFault - 10, RowFault + 10, ColFault + 10)
                    dev_display (SearchImage)
                    disp_rectangle2 (WindowHandleZoom, RowFault, ColFault, 0, 4, 4)
                    stop ()
                    dev_close_window ()
                    dev_set_part (0, 0, Height - 1, Width - 1)
                endif
            endfor
        endif
        if (NumberTeeth2 < 37)
            for j := 0 to NumberTeeth2 - 2 by 1
                if (Distance2[j] > 4.0)
                    RowFault := round(0.5 * (RowEdge12[j + 1] + RowEdge22[j]))
                    ColFault := round(0.5 * (ColEdge12[j + 1] + ColEdge22[j]))
                    disp_rectangle2 (WindowHandle, RowFault, ColFault, 0, 4, 4)
                    dev_open_window (0, Width + 20, 80, 80, 'black', WindowHandleZoom)
                    dev_set_part (RowFault - 10, ColFault - 10, RowFault + 10, ColFault + 10)
                    dev_display (SearchImage)
                    disp_rectangle2 (WindowHandleZoom, RowFault, ColFault, 0, 4, 4)
                    stop ()
                    dev_close_window ()
                    dev_set_part (0, 0, Height - 1, Width - 1)
                endif
            endfor
        endif
        dev_set_color ('yellow')
        stop ()
    endfor
endif
* -------------------  end of the application  -----------------
* clean up
if (USING_TRANSLATE_MEASURE != 0)
    close_measure (MeasureHandle1)
    close_measure (MeasureHandle2)
endif
dev_update_window ('on')
clear_shape_model (ModelID)

在这里插入图片描述
请添加图片描述

Halcon 案例创建匹配模板

在这里插入图片描述

获取图片

dev_update_off ()
dev_close_window ()
* 
* Acquire image
read_image (Image, 'green-dot')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_display (Image)
* 
* Set display settings
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_color ('green')
dev_set_line_width (3)
Message := 'This example shows how to create a shape model'
Message[1] := 'for scale invariant matching and how to save'
Message[2] := 'it in a file.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

分析出匹配区域

* Segment the template region
threshold (Image, Region, 0, 128)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10000, 20000)
fill_up (SelectedRegions, RegionFillUp)
dilation_circle (RegionFillUp, RegionDilation, 5.5)
dev_display (Image)
dev_display (RegionDilation)
disp_message (WindowHandle, 'Template region', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

在这里插入图片描述

创建模板模型,保存到文件中

* Create the shape model
reduce_domain (Image, RegionDilation, ImageReduced)
inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 40)
create_scaled_shape_model (ImageReduced, 5, rad(-45), rad(90), 0, 0.8, 1.0, 0, ['none','no_pregeneration'], 'ignore_global_polarity', 40, 10, ModelID)
dev_display (Image)
dev_display (ModelRegions)
disp_message (WindowHandle, 'Regions of the shape model', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Save the model in a file
write_shape_model (ModelID, 'green-dot.shm')
Message := 'The shape model has been saved in the file'
Message[1] := '\'green-dot.shm\'.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_end_of_program_message (WindowHandle, 'black', 'true')
* 
* Clear the model
clear_shape_model (ModelID)

Halcon 通过图像处理创建模型 ROI模型

在这里插入图片描述

获取图片

* general configuration of HDevelop
dev_update_window ('off')
* image acquisition and window size
open_framegrabber ('File', 1, 1, 0, 0, 0, 0, 'default', -1, 'default', -1, 'default', 'pendulum/pendulum.seq', 'default', -1, 1, FGHandle)
grab_image (ModelImage, FGHandle)
* 获取图片指针
get_image_pointer1 (ModelImage, Pointer, Type, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
* 显示部分图像
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (ModelImage)
* colors and other settings for the visualization
dev_set_color ('cyan')
dev_set_draw ('margin')
dev_set_line_width (2)
stop ()

获取提取到的区域

threshold (ModelImage, BrightRegions, 200, 255)
connection (BrightRegions, ConnectedRegions)
fill_up (ConnectedRegions, FilledRegions)
dev_display (ModelImage)
dev_display (FilledRegions)
stop ()

在这里插入图片描述

选择要识别的区域

select_shape (FilledRegions, Card, 'area', 'and', 1800, 1900)
*显示部分区域
dev_set_part (round(0.2 * Height), round(0.1 * Width) - 1, round(0.7 * Height) - 1, round(0.6 * Width) - 1)
dev_display (ModelImage)
dev_display (Card)
stop ()

在这里插入图片描述

将选择区域裁剪

reduce_domain (ModelImage, Card, ImageCard)

在这里插入图片描述

提取出字符

dev_set_color ('blue')
threshold (ImageCard, DarkRegions, 0, 230)
connection (DarkRegions, ConnectedRegions)
select_shape (ConnectedRegions, Characters, 'area', 'and', 150, 450)
union1 (Characters, CharacterRegion)
dev_display (ModelImage)
dev_display (CharacterRegion)
stop ()

在这里插入图片描述

将字符膨胀处理

dilation_circle (CharacterRegion, ROI, 1.5)
dev_display (ModelImage)
dev_display (ROI)
stop ()

在这里插入图片描述

获取形状创建模板

dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (ModelImage)
*裁剪
reduce_domain (ModelImage, ROI, ImageROI)
* 检测形状
inspect_shape_model (ImageROI, ShapeModelImages, ShapeModelRegions, 5, 25)
select_obj (ShapeModelRegions, ShapeModelRegion, 1)
dev_display (ShapeModelRegion)
create_shape_model (ImageROI, 3, 0, rad(360), 'auto', 'none', 'use_polarity', 30, 10, ModelID)
get_shape_model_contours (ShapeModel, ModelID, 1)
stop ()

在这里插入图片描述

for i := 1 to 30 by 1
    *抓取图片
    grab_image (SearchImage, FGHandle)
    *查找模型
    find_shape_model (SearchImage, ModelID, 0, rad(360), 0.7, 1, 0.5, 'least_squares', 0, 0.5, RowCheck, ColumnCheck, AngleCheck, Score)
    if (|Score| > 0)
        * 获取角度,行列
        vector_angle_to_rigid (0, 0, 0, RowCheck, ColumnCheck, AngleCheck, MovementOfObject)
        * 仿射运算到图片中
        affine_trans_contour_xld (ShapeModel, ModelAtNewPosition, MovementOfObject)
        * 显示被抓取的图片
        dev_display (SearchImage)
        * 显示抓取的模型的位置
        dev_display (ModelAtNewPosition)
    endif
endfor
stop ()
* -------------------  end of the application  -----------------
* clean up
dev_update_window ('on')
clear_shape_model (ModelID)
close_framegrabber (FGHandle)

在这里插入图片描述
在这里插入图片描述

Halcon 亚像素识别

在这里插入图片描述

提取亚像素轮廓

read_image (Image, 'brake_disk/brake_disk_part_01')
dev_update_off ()
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, 640, 640, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_color ('lime green')
dev_set_line_width (3)
*快速二值化选择亮的区域
binary_threshold (Image, Region, 'smooth_histo', 'light', UsedThreshold)
*形成单个连通域
connection (Region, Holes)
*选择面积小的圆
select_shape (Holes, SmallHoles, 'area', 'and', 5000, 10000)
*二值化处理
boundary (SmallHoles, RegionBorder, 'inner_filled')
*膨胀
dilation_circle (RegionBorder, RegionBorderDilation, 3.5)
*四个圆形成一个整体
union1 (RegionBorderDilation, ROI)
*将整体从原图裁剪出来
reduce_domain (Image, ROI, ImageReduced)
*亚像素获取图片圆圈的边沿
edges_sub_pix (ImageReduced, Edges, 'canny', 0.5, 20, 40)
*把检测到的一组点或轮廓线拟合成一个圆形
fit_circle_contour_xld (Edges, 'algebraic', -1, 0, 0, 3, 2, RowCenter, ColumnCenter, Radius, StartPhi, EndPhi, PointOrder)
dev_display (Image)
dev_display (Edges)
disp_message (WindowHandle, 'Extracted edges', 'window', 12, 12, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

在这里插入图片描述

获取平均半径画出圆圈

* Create the circular XLD contour.
dev_clear_window ()
disp_message (WindowHandle, 'First example:\nCreate a shape model from one circular contour', 'window', 12, 12, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*获取平均半径
MeanRadius := mean(Radius)
* 画一个亚像素的圆
gen_circle_contour_xld (ContCircle, 300, 300, MeanRadius, 0, 6.28318, 'positive', 1)
dev_clear_window ()
dev_display (ContCircle)
disp_message (WindowHandle, 'Circular XLD contour from which the\nshape model is created that will be used\nto find individual circles:', 'window', 12, 12, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

在这里插入图片描述

模板匹配

*创建亚像素模型
create_shape_model_xld (ContCircle, 'auto', 0, 0, 'auto', 'auto', 'ignore_local_polarity', 10, ModelID)
*获取模型参数
get_shape_model_params (ModelID, NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Metric, MinContrast)
* 
* Try to find the holes in the brake disc.
*寻找模板
find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0, 'least_squares', 0, 0.9, Row, Column, Angle, Score)

显示匹配结果

* Determine which of the found matches represent the desired holes,
* i.e., which of the circles have a brighter interior.
* 确定找到的匹配项中哪些代表所需的孔、
* 即哪个圆的内部更亮。
IsHole := []
SeamWidth := 5
for Index := 0 to |Row| - 1 by 1
    *转换成极坐标
    polar_trans_image_ext (Image, ImagePolar, Row[Index] + 0.5, Column[Index] + 0.5, 0, 6.28319, 0, MeanRadius + SeamWidth, 1, MeanRadius + SeamWidth + 1, 'nearest_neighbor')
    SequenceInner := [round(MeanRadius) - SeamWidth:round(MeanRadius) - 1]
    *获取灰度值
    get_grayval (ImagePolar, SequenceInner, gen_tuple_const(|SequenceInner|,0), GrayvalInner)
    SequenceOuter := [round(MeanRadius) + 1:round(MeanRadius) + SeamWidth]
    get_grayval (ImagePolar, SequenceOuter, gen_tuple_const(|SequenceOuter|,0), GrayvalOuter)
    if (mean(GrayvalInner) > mean(GrayvalOuter))
        IsHole := [IsHole,true]
    else
        IsHole := [IsHole,false]
    endif
endfor
HoleIndices := find(IsHole,true)
NoHoleIndices := find(IsHole,false)
* 
* Visualize results.
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', subset(Row,HoleIndices), subset(Column,HoleIndices), Angle, 1.0, 1.0, 0)
dev_display_shape_matching_results (ModelID, 'red', subset(Row,NoHoleIndices), subset(Column,NoHoleIndices), Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, 'Undesired result\ndue to missing\npolarity information', 'image', Row[NoHoleIndices[0]] - 2 * MeanRadius, Column[NoHoleIndices[0]] + 1.1 * MeanRadius, 'red', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 
* Determine the polarity information from one correct match.
get_hom_mat2d_from_matching_result (Row[HoleIndices[0]], Column[HoleIndices[0]], Angle[HoleIndices[0]], 1, 1, HomMat2D)
set_shape_model_metric (Image, ModelID, HomMat2D, 'use_polarity')
find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, 'Results using the polarity information', 'window', 12, 12, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

* Determine the polarity information from one correct match.
get_hom_mat2d_from_matching_result (Row[HoleIndices[0]], Column[HoleIndices[0]], Angle[HoleIndices[0]], 1, 1, HomMat2D)
set_shape_model_metric (Image, ModelID, HomMat2D, 'use_polarity')
find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, 'Results using the polarity information', 'window', 12, 12, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

Halcon 识别不等比例的图像

在这里插入图片描述

首先创建一个多边形区域

dev_update_off ()
dev_close_window ()
* 
* For visualization purposes, we specify the number of significant
* bits in the uint2 images.  We do this because this information
* cannot be stored in the image files themselves.
* 设置halcon系统参数
set_system ('int2_bits', 10)
read_image (Image, 'smd/smd_capacitors_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_display (Image)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
Message := 'This program shows how to use shape-based matching'
Message[1] := 'to find SMD capacitors that exhibit independent'
Message[2] := 'size changes in the row and column direction in'
Message[3] := 'images with a depth of 10 bits.'
Message[4] := 'First a synthetic model for the SMD capacitors'
Message[5] := 'is created. In the next step the created model'
Message[6] := 'is used to find the SMD capacitors.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_set_color ('green')
dev_set_line_width (3)
* 
* Create a synthetic model for the SMD capacitors.  This is just
* a rectangle with rounded corners.
* 形成一个多边形区域
gen_contour_polygon_rounded_xld (Contour, [50,100,100,50,50], [50,50,150,150,50], [6,6,6,6,6], 1)
* 形成一个新的空白图像
gen_image_const (Image, 'byte', 200, 150)
* 绘制图像灰度值为128
paint_xld (Contour, Image, ImageModel, 128)

在这里插入图片描述

通过多边形区域创建模板

* 创建不等比例模型
create_aniso_shape_model (ImageModel, 'auto', -rad(10), rad(20), 'auto', 0.9, 1.7, 'auto', 0.9, 1.1, 'auto', 'none', 'use_polarity', 'auto', 20, ModelID)
*获取模型轮廓
get_shape_model_contours (ModelContours, ModelID, 1)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

显示

* Find the models for the SMD capacitors in the images
* and display the number of found models an the recognition time
* and the model's scale
for J := 1 to 4 by 1
    read_image (Image, 'smd/smd_capacitors_' + J$'02d')
    dev_display (Image)
    *计算时间
    count_seconds (S1)
    *匹配
    find_aniso_shape_model (Image, ModelID, -rad(10), rad(20), 0.9, 1.7, 0.9, 1.1, 0.7, 0, 0.5, 'least_squares', 0, 0.8, Row, Column, Angle, ScaleR, ScaleC, Score)
    count_seconds (S2)
    *计算时间
    Time := (S2 - S1) * 1000
    Num := |Score|
    * Display the found models and the recognition time
    disp_message (WindowHandle, Num$'d' + ' models found in ' + Time$'5.2f' + ' ms', 'window', 12, 12, 'black', 'true')
    *平均列
    MeanColumn := mean(Column)
    for I := 0 to Num - 1 by 1
        * Display the found model.
        *初始化一个空的仿射变换矩阵
        hom_mat2d_identity (HomMat2D)
        hom_mat2d_scale (HomMat2D, ScaleR[I], ScaleC[I], 0, 0, HomMat2D)
        hom_mat2d_rotate (HomMat2D, Angle[I], 0, 0, HomMat2D)
        hom_mat2d_translate (HomMat2D, Row[I], Column[I], HomMat2D)
        affine_trans_contour_xld (ModelContours, ContoursTrans, HomMat2D)
        dev_display (ContoursTrans)
        * 
        * Display the model's scale next to the found model
        ScaleRowStr := 'ScaleRow=' + ScaleR[I]$'5.3f'
        ScaleColStr := 'ScaleCol=' + ScaleC[I]$'5.3f'
        get_string_extents (WindowHandle, ScaleRowStr, AscentStr, DescentStr, WidthStr, HeightStr)
        if (Column[I] <= MeanColumn)
            disp_message (WindowHandle, [ScaleRowStr,ScaleColStr], 'image', Row[I] - 20, Column[I] - 60 - WidthStr, 'green', 'false')
        else
            disp_message (WindowHandle, [ScaleRowStr,ScaleColStr], 'image', Row[I] - 20, Column[I] + 60, 'green', 'false')
        endif
    endfor
    * Deactivate the following lines to run the programm without breaks
    if (J < 4)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor
* Reset the number of significant bits of uint2 images to unknown.
set_system ('int2_bits', -1)

在这里插入图片描述

Halcon 匹配包装袋案例

在这里插入图片描述

创建窗口

dev_update_off ()
read_image (ModelImage, 'food/cocoa_package_model')
dev_close_window ()
dev_open_window_fit_image (ModelImage, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

创建模型

*创建匹配模型
create_shape_model (ModelImage, 'auto', rad(-20), rad(40), 'auto', 'auto', 'use_polarity', [40,60,'auto_min_size'], 10, ModelID)
*获取匹配形状
get_shape_model_contours (ModelContours, ModelID, 1)
area_center (ModelImage, Area, Row, Column)
*进行仿射运算
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, Row, Column, HomMat2DTranslate)
affine_trans_contour_xld (ModelContours, ContoursAffineTrans, HomMat2DTranslate)
dev_set_line_width (2)
dev_set_color ('yellow')
dev_display (ModelImage)
dev_display (ContoursAffineTrans)
disp_message (WindowHandle, 'Model image and contours', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

在这里插入图片描述

对图像进行匹配

NumImages := 13
for Index := 1 to NumImages by 1
    read_image (Image, 'food/cocoa_packages_' + Index$'02')
    * Reduce the image resolution for a speed-up
    dev_resize_window_fit_image (Image, 0, 0, -1, -1)
    dev_display (Image)
    disp_message (WindowHandle, 'Search...', 'window', 12, 12, 'black', 'true')
    count_seconds (S1)
    * Find the deformed model in the search image
    * and display the results
    * 查找模板
    find_shape_model (Image, ModelID, rad(-20), rad(40), 0.6, 0, 0.5, ['least_squares','max_deformation 16'], 0, 0.4, Row, Column, Angle, Score)
    * 计算匹配时间
    count_seconds (S2)
    Time := (S2 - S1) * 1000
    *设置颜色
    dev_set_color ('green')
    *展示匹配结果
    dev_display_shape_matching_results (ModelID, 'green', Row, Column, Angle, 1, 1, 0)
    *展示匹配的时间
    disp_message (WindowHandle, |Score| + ' matches found in ' + Time$'3.1f' + ' ms', 'window', 12, 12, 'black', 'true')
    *展示匹配的相似度
    disp_message (WindowHandle, 'Score: ' + Score$'.2f', 'image', 350, Column - 80, 'black', 'true')
    if (Index < NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

Halcon 创建模板进行匹配

在这里插入图片描述

* --------------------------------------------------------
* This example program shows how to reuse a created model.
* --------------------------------------------------------
* general configuration of HDevelop
dev_update_window ('off')
* image acquisition and window size
read_image (ModelImage, 'rings_and_nuts')
get_image_pointer1 (ModelImage, Pointer, Type, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'white', WindowHandle)
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (ModelImage)
* colors and other settings for the visualization
dev_set_color ('cyan')
dev_set_draw ('margin')
dev_set_line_width (2)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* ------------  start of the first application  ------------
* -> create the model
Row := 324
Column := 279
Radius := 60
gen_circle (ROI1, Row, Column, Radius)
gen_circle (ROI2, Row, Column, 0.5 * Radius)
* 获取两个区域的交集
difference (ROI1, ROI2, ModelROI)
* 将原图和相交的图片裁剪出来获得ImageROI
reduce_domain (ModelImage, ModelROI, ImageROI)
* 创建匹配模板
create_scaled_shape_model (ImageROI, 'auto', -rad(30), rad(60), 'auto', 0.6, 1.4, 'auto', 'none', 'use_polarity', 60, 10, ModelID)
* 检查已创建的形状模型,并获取有关模型参数的信息
inspect_shape_model (ImageROI, ShapeModelImage, ShapeModelRegion, 1, 30)
dev_clear_window ()
dev_display (ShapeModelRegion)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* step 1: store the model (including the XLD)
ModelFile := 'model_nut.sbm'
* 写入模板图像
write_shape_model (ModelID, ModelFile)
* -> additionally, we store the model region
ModelRegionFile := 'model_region_nut.png'
write_image (ImageROI, 'png', 0, ModelRegionFile)
* -> now we destroy the model and start anew
clear_shape_model (ModelID)
* ------------  start of the second application  ------------
* step 2: read the model from file
* 读取模板
read_shape_model (ModelFile, ReusedModelID)
* -> access the parameters used for creating the model
* 获取轮廓
get_shape_model_contours (ReusedShapeModel, ReusedModelID, 1)
* 获取原点参数
get_shape_model_origin (ReusedModelID, ReusedRefPointRow, ReusedRefPointCol)
* 获取参数
get_shape_model_params (ReusedModelID, NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Metric, MinContrast)
* -> access the model region
read_image (ImageModelRegion, 'model_region_nut.png')
* 由图像获取到对应的区域
get_domain (ImageModelRegion, DomainModelRegion)
dev_display (ImageModelRegion)
dev_display (DomainModelRegion)
stop ()
* step 3: search for the objects
read_image (SearchImage, 'rings_and_nuts')
dev_display (SearchImage)
* 查找到模板
find_scaled_shape_model (SearchImage, ReusedModelID, AngleStart, AngleExtent, ScaleMin, ScaleMax, 0.65, 0, 0, 'least_squares', 0, 0.8, RowCheck, ColumnCheck, AngleCheck, ScaleCheck, Score)
for i := 0 to |Score| - 1 by 1
    get_hom_mat2d_from_matching_result (RowCheck[i], ColumnCheck[i], AngleCheck[i], ScaleCheck[i], ScaleCheck[i], MoveAndScalingOfObject)
    affine_trans_contour_xld (ReusedShapeModel, ModelAtNewPosition, MoveAndScalingOfObject)
    dev_display (ModelAtNewPosition)
endfor
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
clear_shape_model (ModelID)
* ------------  end of the application  ------------
* clean up
dev_update_window ('on')

Halcon 案例模板匹配与测量

在这里插入图片描述

思路:
1.先进行模板匹配找出要匹配的模板(如案例中的字符)
2.获取模板的角度位置
3.得到角度、位置后对物体进行测量

* This example program shows the use of pattern matching with shape models
* to locate an object.  Furthermore, it shows how to use the detected position
* and rotation of the object to construct search spaces for inspection tasks.
* In this particular example, the print on an IC is used to find the IC.  From the
* found position and rotation, two measurement rectangles are constructed to
* measure the spacing between the leads of the IC.  Because of the lighting
* used in this example, the leads have the saturated gray value of 255 at several
* positions and rotations, which enlarges the apparent width of the leads, and
* hence seems to reduce the spacing between the leads, although the same
* board is used in all images.
dev_update_pc ('off')
dev_update_window ('off')
dev_update_var ('off')
open_framegrabber ('File', 1, 1, 0, 0, 0, 0, 'default', -1, 'default', -1, 'default', 'board/board.seq', 'default', -1, 1, FGHandle)
grab_image (Image, FGHandle)
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_open_window (Height + 70, 0, Width, 120, 'black', WindowHandleText)
dev_set_window (WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
set_display_font (WindowHandleText, 16, 'mono', 'true', 'false')
dev_set_color ('red')
dev_display (Image)
Row1 := 188
Column1 := 182
Row2 := 298
Column2 := 412
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
area_center (Rectangle, Area, Row, Column)
Rect1Row := -102
Rect1Col := 5
Rect2Row := 107
Rect2Col := 5
RectPhi := 0
RectLength1 := 170
RectLength2 := 5
gen_rectangle2 (Rectangle1, Row + Rect1Row, Column + Rect1Col, RectPhi, RectLength1, RectLength2)
gen_rectangle2 (Rectangle2, Row + Rect2Row, Column + Rect2Col, RectPhi, RectLength1, RectLength2)
reduce_domain (Image, Rectangle, ImageReduced)
create_shape_model (ImageReduced, 4, 0, rad(360), rad(1), 'none', 'use_polarity', 30, 10, ModelID)
get_shape_model_contours (ShapeModel, ModelID, 1)
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, Row, Column, HomMat2DTranslate)
affine_trans_contour_xld (ShapeModel, ShapeModelTrans, HomMat2DTranslate)
dev_display (Image)
dev_set_color ('green')
dev_display (ShapeModelTrans)
dev_set_color ('blue')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Rectangle1)
dev_display (Rectangle2)
dev_set_draw ('fill')
dev_set_line_width (1)
dev_set_color ('yellow')
disp_message (WindowHandle, ['Press left button to start','and stop the demo'], 'window', 12, 12, 'black', 'true')
get_mbutton (WindowHandle, Row3, Column3, Button1)
wait_seconds (0.5)
Button := 0
while (Button != 1)
    dev_set_window (WindowHandle)
    dev_set_part (0, 0, Height - 1, Width - 1)
    grab_image (ImageCheck, FGHandle)
    dev_display (ImageCheck)
    count_seconds (S1)
    find_shape_model (ImageCheck, ModelID, 0, rad(360), 0.7, 1, 0.5, 'least_squares', 4, 0.7, RowCheck, ColumnCheck, AngleCheck, Score)
    count_seconds (S2)
    dev_display (ImageCheck)
    if (|Score| > 0)
        dev_set_color ('green')
        hom_mat2d_identity (HomMat2DIdentity)
        hom_mat2d_translate (HomMat2DIdentity, RowCheck, ColumnCheck, HomMat2DTranslate)
        hom_mat2d_rotate (HomMat2DTranslate, AngleCheck, RowCheck, ColumnCheck, HomMat2DRotate)
        affine_trans_contour_xld (ShapeModel, ShapeModelTrans, HomMat2DRotate)
        dev_display (ShapeModelTrans)
        affine_trans_pixel (HomMat2DRotate, Rect1Row, Rect1Col, Rect1RowCheck, Rect1ColCheck)
        affine_trans_pixel (HomMat2DRotate, Rect2Row, Rect2Col, Rect2RowCheck, Rect2ColCheck)
        gen_rectangle2 (Rectangle1Check, Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2)
        gen_rectangle2 (Rectangle2Check, Rect2RowCheck, Rect2ColCheck, AngleCheck, RectLength1, RectLength2)
        dev_set_color ('blue')
        dev_set_draw ('margin')
        dev_set_line_width (3)
        dev_display (Rectangle1Check)
        dev_display (Rectangle2Check)
        dev_set_draw ('fill')
        count_seconds (S3)
        gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1)
        gen_measure_rectangle2 (Rect2RowCheck, Rect2ColCheck, AngleCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2)
        measure_pairs (ImageCheck, MeasureHandle1, 2, 90, 'positive', 'all', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, IntraDistance1, InterDistance1)
        measure_pairs (ImageCheck, MeasureHandle2, 2, 90, 'positive', 'all', RowEdgeFirst2, ColumnEdgeFirst2, AmplitudeFirst2, RowEdgeSecond2, ColumnEdgeSecond2, AmplitudeSecond2, IntraDistance2, InterDistance2)
        count_seconds (S4)
        dev_set_color ('red')
        disp_line (WindowHandle, RowEdgeFirst1 - RectLength2 * cos(AngleCheck), ColumnEdgeFirst1 - RectLength2 * sin(AngleCheck), RowEdgeFirst1 + RectLength2 * cos(AngleCheck), ColumnEdgeFirst1 + RectLength2 * sin(AngleCheck))
        disp_line (WindowHandle, RowEdgeSecond1 - RectLength2 * cos(AngleCheck), ColumnEdgeSecond1 - RectLength2 * sin(AngleCheck), RowEdgeSecond1 + RectLength2 * cos(AngleCheck), ColumnEdgeSecond1 + RectLength2 * sin(AngleCheck))
        disp_line (WindowHandle, RowEdgeFirst2 - RectLength2 * cos(AngleCheck), ColumnEdgeFirst2 - RectLength2 * sin(AngleCheck), RowEdgeFirst2 + RectLength2 * cos(AngleCheck), ColumnEdgeFirst2 + RectLength2 * sin(AngleCheck))
        disp_line (WindowHandle, RowEdgeSecond2 - RectLength2 * cos(AngleCheck), ColumnEdgeSecond2 - RectLength2 * sin(AngleCheck), RowEdgeSecond2 + RectLength2 * cos(AngleCheck), ColumnEdgeSecond2 + RectLength2 * sin(AngleCheck))
        dev_set_line_width (1)
        NumLeads := |IntraDistance1| + |IntraDistance2|
        MinDistance := min([InterDistance1,InterDistance2])
        dev_set_window (WindowHandleText)
        dev_set_part (0, 0, 119, Width - 1)
        dev_clear_window ()
        disp_message (WindowHandleText, 'Matching: Time: ' + ((S2 - S1) * 1000)$'5.2f' + 'ms , Score: ' + Score$'7.5f', 'image', 20, 20, 'green', 'false')
        disp_message (WindowHandleText, 'Measure:  Time: ' + ((S4 - S3) * 1000)$'5.2f' + ' ms, Num. leads: ' + NumLeads$'2d', 'image', 50, 20, 'red', 'false')
        disp_message (WindowHandleText, '          Min. lead dist: ' + MinDistance$'6.3f', 'image', 80, 20, 'red', 'false')
    endif
    dev_error_var (Error, 1)
    dev_set_check ('~give_error')
    get_mposition (WindowHandle, R, C, Button)
    dev_error_var (Error, 0)
    dev_set_check ('give_error')
    if (Error != H_MSG_TRUE)
        Button := 0
    endif
endwhile
dev_set_window (WindowHandleText)
dev_close_window ()
close_framegrabber (FGHandle)

Halcon 多模板与多图像的匹配

在这里插入图片描述

* This example program shows how to use HALCON's shape-based matching
* to find multiple different models in one call to find_shape_models.  Note that this
* is one mode of operation that is frequently useful.  However, the number of
* applications that can be solved with this mechanism is much larger.  For
* another application where finding multiple models in one call is useful are
* applications where the same object can only occur in small angle ranges
* around a discrete set of angles, e.g., 0°, 90°, 180°, and 270°.  In these cases,
* it would be wasteful to train the model for the full 360° rotation range and to
* match the model in this range.  Instead, four models using the small angle
* ranges around the discrete set of angles should be generated from the same
* model image and used in the matching stage using four different angle ranges.
dev_update_pc ('off')
dev_update_window ('off')
dev_update_var ('off')
dev_close_window ()
dev_open_window (0, 0, 646, 482, 'black', WindowHandle)
dev_set_part (0, 0, 481, 645)
set_display_font (WindowHandle, 20, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
* These colors will be used to graphically discern the different models in the
* visualization code below.
Colors := ['red','green','cyan']
* The models will be generated from hard-coded rectangles given by the
* following coordinates:
Row1 := [135,150,185]
Column1 := [250,170,220]
Row2 := [375,310,335]
Column2 := [355,395,375]
* The object Models will hold a set of XLD contours that represent the different
* models.  They are used below to overlay the found models on the current
* image.  XLD contours are used because they can be transformed much faster
* than regions.  This creates a slight problem because in general multiple XLD
* contours will represent one model.  Therefore, the start and end indices of the
* different models will be stored in IndexS and IndexE, respectively.
* 产生一个空的轮廓
gen_empty_obj (Models)
IndexS := []
IndexE := []
* The variable ModelIDs holds the different models that are created below.
ModelIDs := []
* Likewise, RowsRef and ColumnsRef store the reference points of the different
* models.  They are necessary to transform the models to the found instances
* in the current image.

* 准备模板
for J := 1 to 3 by 1
    read_image (Image, 'metal-parts/metal-part-model-' + J$'02d')
    dev_display (Image)
    dev_set_color ('green')
    * 设置显示位置
    set_tposition (WindowHandle, 20, 20)
    * 写入字体
    write_string (WindowHandle, 'Generating shape model ' + J$'d')
    * 绘制矩形ROI
    gen_rectangle1 (Rectangle, Row1[J - 1], Column1[J - 1], Row2[J - 1], Column2[J - 1])
    * 获取中心区域
    area_center (Rectangle, Area, Row, Column)
    * 将区域裁剪
    reduce_domain (Image, Rectangle, ImageReduced)
    * Although we will use get_shape_model_contours below to obtain the
    * representation of the model, we extract a model representation here using
    * inspect_shape_model because this enables us to display the representation
    * of the model while the model is being created.
    * 检测模型特性  inspect_shape_model(图像,得到金字塔图像,得到对应的区域,金字塔层数,对比度)
    inspect_shape_model (Image, ModelImages, ModelRegions, 1, 30)
    * Since the shape models contain a few extraneous edges, they will be
    * removed here to give a slightly nicer visualization.
    * 断成不同的连通域
    connection (ModelRegions, ConnectedRegions)
    * 选择区域
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20, 100000)
    * 将选择的区域联合
    union1 (SelectedRegions, ModelRegions)
    * 转换骨架到XLD轮廓
    gen_contours_skeleton_xld (ModelRegions, ModelContours, 1, 'filter')
    dev_set_color ('red')
    dev_display (ModelContours)
    * 创建形状模板
    create_shape_model (ImageReduced, 5, rad(0), rad(360), 'auto', 'pregeneration', 'use_polarity', 30, 7, ModelID)
    * 获取形状轮廓
    get_shape_model_contours (ModelCont, ModelID, 1)
    * 根据特征,选择特定的亚像素轮廓或多边形
    select_shape_xld (ModelCont, ModelContours, 'contlength', 'and', 20, 1000)
    * Count how many XLD contours there are in the current model and in the
    * already stored models.  This is necessary to compute IndexS and IndexE.
    * 计算轮廓数量
    count_obj (ModelContours, NumModel)
    * 计算空的轮廓
    count_obj (Models, NumModels)
    * 将原有的轮廓放入新的轮廓中
    concat_obj (Models, ModelContours, Models)
    * 轮廓起始索引,轮廓数量增加 IndexS:=[1,5,10]
    IndexS := [IndexS,NumModels + 1]
    * 轮廓的个数,第一个轮廓有4个,第二个有4+5,第三个有4+5+2个   IndexE:=[4,9,11]
    IndexE := [IndexE,NumModels + NumModel]
    * 模型句柄增加  ModelIDs :=[0,1,2]
    ModelIDs := [ModelIDs,ModelID]
endfor
dev_set_color ('yellow')
set_tposition (WindowHandle, 50, 20)
write_string (WindowHandle, 'Press left button to start')
set_tposition (WindowHandle, 80, 20)
write_string (WindowHandle, 'and stop the demo.')
get_mbutton (WindowHandle, Row3, Column3, Button1)
wait_seconds (0.5)
dev_set_color ('red')
Button := 0
ImgNo := 1
* 点击开始识别
while (Button != 1)
    * 读取图片
    read_image (Image, 'metal-parts/metal-parts-' + ImgNo$'02d')
    * 计算秒数
    count_seconds (S1)
    * find_shape_models查找模板Model:=0 查找到 ModelIDs数组中的第一个模板
    find_shape_models (Image, ModelIDs, rad(0), rad(360), 0.5, 0, 0.5, 'least_squares', 0, 0.8, Row, Column, Angle, Score, Model)
    count_seconds (S2)
    Time := (S2 - S1) * 1000
    dev_display (Image)
    Num := |Score|
    for J := 0 to Num - 1 by 1
        * Select the correct XLD contours from the Models object.
        * 复制一个目标到模板中
        copy_obj (Models, ModelSelected, IndexS[Model[J]], IndexE[Model[J]] - IndexS[Model[J]] + 1)
        * Compute the transformation from the model object to the current instance.
        * Row[J], Column[J], Angle[J] 对应117行的行列角度
        vector_angle_to_rigid (0, 0, 0, Row[J], Column[J], Angle[J], HomMat2D)
        affine_trans_contour_xld (ModelSelected, ModelTrans, HomMat2D)
        dev_set_color (Colors[Model[J]])
        dev_display (ModelTrans)
    endfor
    * 显示
    dev_set_color ('yellow')
    set_tposition (WindowHandle, 20, 20)
    if (Num == 1)
        write_string (WindowHandle, Num$'1d' + ' object found in ' + Time$'4.2f' + 'ms')
    else
        write_string (WindowHandle, Num$'1d' + ' objects found in ' + Time$'4.2f' + 'ms')
    endif
    ImgNo := ImgNo + 1
    if (ImgNo > 15)
        ImgNo := 1
    endif
    dev_error_var (Error, 1)
    dev_set_check ('~give_error')
    get_mposition (WindowHandle, R, C, Button)
    dev_error_var (Error, 0)
    dev_set_check ('give_error')
    if (Error != H_MSG_TRUE)
        Button := 0
    endif
endwhile

文章来源:https://blog.csdn.net/weixin_45672157/article/details/134998447
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。