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

news2024/11/14 21:28:10

文章目录

  • halcon 案例 基于缩放比
  • halcon 案例 测单个剃须刀片
  • Halcon 案例创建匹配模板
  • Halcon 通过图像处理创建模型 ROI模型
  • Halcon 亚像素识别
  • Halcon 识别不等比例的图像
  • Halcon 匹配包装袋案例
  • Halcon 创建模板进行匹配
  • Halcon 案例模板匹配与测量
  • Halcon 多模板与多图像的匹配

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1369325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CMake入门教程【核心篇】导入外部库Opencv

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 环境准备示例:在Windows上配置OpenCV路径示例:在Linux上配置OpenCV路径环境准备 首先确保你的系统中安装了CMake。可以通过以下命令安装: Windows: 下载并…

猴子选大王

思路&#xff1a;首先举个例子&#xff1a;当N 5 时 1 2 3 4 5 3 3 3 3 输出4 请观看代码 …

光纤知识总结

1光纤概念&#xff1a; 光导纤维&#xff08;英语&#xff1a;Optical fiber&#xff09;&#xff0c;简称光纤&#xff0c;是一种由玻璃或塑料制成的纤维&#xff0c;利用光在这些纤维中以全内反射原理传输的光传导工具。 微细的光纤封装在塑料护套中&#xff0c;使得它能够…

定时器中断控制的独立式键盘扫描实验

#include<reg51.h> //包含51单片机寄存器定义的头文件 sbit S1P1^4; //将S1位定义为P1.4引脚 sbit S2P1^5; //将S2位定义为P1.5引脚 sbit S3P1^6; //将S3位定义为P1.6引脚 sbit S4P1^7; //将S4位定义为P1.7引脚 unsigned char keyval; /…

在黑马程序员大学的2023年终总结

起笔 时间真快&#xff0c;转眼又是年末。是时候给2023做个年终总结了&#xff0c;为这一年的学习、生活以及成长画上一个圆满的句号。 这一年相比去年经历了很多事情&#xff0c;接下来我会一一说起 全文大概4000字&#xff0c;可能会占用你15分钟左右的时间 经历 先来给大…

Python学习之路-Hello Python

Python学习之路-Hello Python Python解释器 简介 前面说到Python是解释型语言&#xff0c;Python解释器的作用就是用于"翻译"Python程序。Python规定了一个Python语法规则&#xff0c;根据该规则可编写Python解释器。 常见的Python解释器 CPython&#xff1a;官方…

哈希-力扣01两数之和

题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺…

云仓酒庄的品牌雷盛红酒LEESON分享什么是“小农香槟”?

云仓酒庄的品牌雷盛红酒LEESON分享说起香槟&#xff0c;第一时间会想到法国&#xff0c;因为只有法国的起泡酒才能叫“香槟”。那么&#xff0c;什么又是“小农香槟”呢&#xff1f; 小农香槟是相对大厂香槟而命名的&#xff0c;是指葡萄果农自产、自酿、自销的香槟&#xff0…

TS中的类

目录 ES6的类 类的概念 类的构成 类的创建 声明 构造函数 定义内容 创建实例 TS中的类 类声明 构造函数 属性和方法 实例化类 继承 访问修饰符 public private protected 成员访问修饰符的使用原则 访问器 只读成员与静态成员 readonly static 修饰符总…

MySQL之导入导出远程备份

目录 一. navicat导入导出 二. mysqldump命令导入导出 导入 导出 三. load data infile命令导入导出 导入 导出 四. 远程备份 导入 导出 思维导图 一. navicat导入导出 导入&#xff1a;右键➡运行SQL文件 导出&#xff1a;选中要导出的表➡右键➡转储SQL文件➡数据和结…

【PB续命07】JDBC连接达梦数据库

JDBC(Java DataBase Connectivity) 称为Java数据库连接&#xff0c;它是一种用于数据库访问的应用程序API&#xff0c;由一组用Java语言编写的类和接口组成&#xff0c;有了JDBC就可以用同一的语法对多种关系数据库进行访问&#xff0c;而不用担心其数据库操作语言的差异。 有了…

基于Python的货币识别技术实现

目录 介绍本文的目的和意义货币识别技术的应用场景 货币识别的基本原理图像处理技术在货币识别中的应用特征提取方法&#xff1a;SIFT、HOG等支持向量机&#xff08;SVM&#xff09;分类器的使用 实现过程数据集的收集和预处理特征提取和训练分类器 参考文献 介绍 本文的目的和…

Spring事务控制见解6

7.Spring事务控制 7.1.事务介绍 7.1.1.什么是事务&#xff1f; 当你需要一次执行多条SQL语句时&#xff0c;可以使用事务。通俗一点说&#xff0c;如果这几条SQL语句全部执行成功&#xff0c;则才对数据库进行一次更新&#xff0c;如果有一条SQL语句执行失败&#xff0c;则这…

软件测试|Chrome 115之后的版本,如何更新driver?

问题描述 前两天在运行一个web自动化测试脚本时&#xff0c;报了如下的错误&#xff0c;This version of ChromeDriver only supports Chrome version 113 Current browser version is 115.0.5790.110 with binary&#xff0c;如下图所示&#xff1a; 该报错提示我&#xff0c…

灵魂三连问:是5G卡吗?支持5G吗?是5G套餐吗

关于5G的问题&#xff0c;小伙伴们的疑问是不是很多&#xff0c;它和4G到底有什么区别呢&#xff1f;什么是5G卡&#xff1f;什么是5G套餐&#xff1f;支持5G吗&#xff1f;什么是5G基站&#xff1f;我想大家现在一定是晕的&#xff0c;下面小编来给大家解惑&#xff01; 1&…

C语言入门教程,C语言学习教程(第二部分:C语言初探)一

第二部分&#xff1a;C语言初探 本章主要讲解C语言编程环境的搭建&#xff0c;让大家能够编写并运行C语言代码&#xff0c;其中&#xff0c;编译器是重点讲解内容。 本章还对一段简单的C语言代码进行了分析&#xff0c;让大家明白了C语言程序的基本结构。 一、第一个C语言程序…

【教学类-45-03】X-Y之间的“三连加减“题(a+b-c=)

作品展示&#xff1a; 背景需求&#xff1a; 【教学类-45-02】X-Y之间的“三连减“题(a-b-c)-CSDN博客文章浏览阅读465次&#xff0c;点赞15次&#xff0c;收藏7次。【教学类-45-02】X-Y之间的"三连减"题(a-b-c)https://blog.csdn.net/reasonsummer/article/details…

前端实现搜索功能

最近遇到一个需求,用户在输入框输入关键字之后,点击搜索按钮后进行搜索,如下图,选中的数据在下面,上面展现的是搜索后的数据,现在选中了2条数据: 当用户输入KET后点击搜索,搜出的结果有16条,勾选全选选中后,将选中的16条的数据加到之前已选的2条数据里,于是此时已选…

JavaScript版数据结构与算法(一)栈、队列、链表、集合、树

一、前言 为什么要学习数据结构与算法&#xff1f;最重要的就是面试要考算法&#xff0c;另外就是如果在实际工作当中&#xff0c;能够使用算法优化代码&#xff0c;会提升代码质量和运行效率&#xff0c;作为一名前端人员可能在实际中用的并不是特别多。数据结构与算法是分不…

如何使用内网穿透实现iStoreOS软路由公网远程访问局域网电脑桌面

文章目录 简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 软路由是PC的硬件加上路由系统来实现路由器的功能&#xff0c;也可以说是使用软件达成路由功能的路由器。 使用软路由控制局域网内计算机的好处&#xff1a…