Halcon模板匹配

模板匹配- ShapeModel(形状模板)

介绍:

Halcon 的ShapeModel 是halcon软件中多种匹配方式的一种,这种叫做形状模板,这种方式的模板我们通常用在被检测物的外形,轮廓固定且背景很干净,就是被测物和他的背景对比度很强。如果说被测物的外形或者轮廓会发生非常大的形变,则这种ShapeModel就不适用。

使用方法:

1.导入图片

2.选择一个被测物,画一个搜索区域框中这个被测物。

3.缩小区域,只让被框中的被测物显示

4.创建ShapelModel

5.保存ShapeModel 至本地

6.一旦模板被创建后,就不再需要创建的过程代码了

7.从本地读取ShapelModel

8.寻找模板

9.如果说找到了模板,则从Model中获取轮廓,变换到找到的被测物的身上。

10.结束

算子分析:

1
create_shape_model(ObjectModel : Image, NumLevels : int, AngleStart : int, AngleExtent : int, AngleStep : string, ScaleMin : double, ScaleMax : double, ScaleStep : double, Optimization : string, Metric : string, Contrast : double, MinContrast : double, ModelID : int)

create_shape_model是Halcon的一个算子,用于创建形状模板以进行目标检测和匹配。该算子涉及参数如金字塔层数、旋转角度范围和缩放比例,以及匹配度量和优化模式。形状模板的质量直接影响后续的检测和匹配效果,因此参数调整至关重要

参数说明:

ObjectModel:包含待创建模板的形状的二值图像。
NumLevels:金字塔层数,用于多尺度匹配。
AngleStart:起始角度(以弧度为单位),用于模板的旋转范围。
AngleExtent:旋转角度的范围(以弧度为单位)。
AngleStep:旋转角度的步长,可以是’auto’或具体的值。
Optimization:优化模式,用于加速模板匹配。
Metric:模板匹配的度量方式。‘use_polarity’
Contrast:对比度增强系数。
MinContrast:最小对比度阈值。
ModelID:输出的模板ID。

特别需要注意的是(创建模板的时候,比方我们想要-10°到10°的创建,我们不能写成-1010 我们应该写成-1020)

AngleStart:起始角度 比方我们设置-10° 就是起始的角度,怎么样搞到10? -10+20=10° 所以说下一个并不是角度的终点,AngleExtent:旋转角度的范围 。

Metric:模板的极性。 什么叫极性? 假如被测物是白色,背景是黑色。 这个叫做一种极性。 被测物突变成黑色,背景突变成白色又是另外一种极性。halcon中通过 ‘use_polarity’ 使用极性。

1
find_shape_model(Image : : ModelID, AngleStart, AngleExtent, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels, Greediness : Row, Column, Angle, Score)

寻找形状模板,一旦形状模板被创建后,会得到一个ModelID 叫做模板句柄。后续我们使用Find_shapel_model 来寻找模板了。

参数说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Image:待寻找的图片。
ModelID:模板的句柄。
AngleStart:起始角度(以弧度为单位),用于模板的旋转范围。
AngleExtent:旋转角度的范围(以弧度为单位)。
MinScore:最小得分,也叫做合格分数取值范围(0-1)。
NumMatches:匹配的个数(0代表有多少找多少,1代表找一个,2代表找2个....n代表找n个)。
MaxOverlap:最大重叠度,默认0.5 如果被测物在图像上面发生交叠,要观察交叠程度,设置为0.5以上则交叠的两个物体会被识别成2个,如果设置为0。则交叠的两个物体会被识别成1个)
SubPixel:是否采用亚像素精度查找算法(使用会找的更准,但是耗时增加)。
NumLevels:金字塔极数,0代表与创建时候的轮廓一模一样,数值越大,速度越快,但是越不精准。
Greediness:贪婪度(0-1)请联想阿里巴巴与40大盗,越贪婪,越乱找,越不贪婪,越精准。
Row:被找到的物体的行
Column:被找到的物体的列
Angle:被找到物体的角度(halcon里使用弧度制表示 1rad≈57.3°)
Score:被找到物体的得分

有一些课堂的思路草图:

image-20250312092706327

image-20250312092747500

image-20250312092812059

image-20250312092833369

image-20250312110603787

课堂的代码之单模板匹配:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
*读取图片
read_image (T2, 'D:/人工智能1班/第14天_halcon多模板匹配/t (2).jpeg')

*1.选择一个区域 作为模板

* gen_rectangle1 (ROI_0, 317.951, 473.835, 387.548, 544.382)
* erosion_circle (ROI_0, ROI_0, 10)
*缩小区域
* reduce_domain (T2, ROI_0, ImageReduced)

*清屏显示

* dev_clear_window ()
* dev_display (ImageReduced)
*2.自动创建形状模板
*如果你需要创建的模板区域 在-10~10 生效 。你需要在创建的时候输入一个 -10~ -10*-2=20
* create_shape_model (ImageReduced, 'auto', rad(-10), rad(20),\
'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)

*3.模板的本地化存储

* write_shape_model (ModelID, 'Model.shm')


*4.读取本地化存储的模板
read_shape_model ('./Model.shm', ModelID)


*寻找模板 (-10 到20度角度测试)
for Index := -10 to 20 by 1
rotate_image (T2, ImageRotate, Index, 'constant')
find_shape_model (ImageRotate, ModelID, rad(-10), rad(20), 0.5, 1, 0.5,\
'least_squares', 0, 0.9, Row, Column, Angle, Score)

*判断 Row,column,angle,score中的任意一个 控制变量 看他为不为空或者数量是否大于1
if(|Row|>0)
*拿到模板的轮廓
get_shape_model_contours (ModelContours, ModelID, 1)
*根据起点到终点的状态 创建一个仿射变换的关系 刚体变换
vector_angle_to_rigid (0, 0, 0, Row, Column, Angle, HomMat2D)
*应用变换关系 把模板的轮廓xld 转到新的地方去
affine_trans_contour_xld (ModelContours, ContoursAffineTrans, HomMat2D)
dev_set_line_width (5)
dev_set_color ('green')
dev_clear_window ()
dev_display (ImageRotate)
dev_display (ContoursAffineTrans)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 26, 'sans', 'true', 'false')
disp_message (WindowHandle, Index+' °', 'window', 30, 30, 'blue', 'true')
endif
stop()
endfor

课堂的代码之多模板匹配:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
*读取图片
read_image (T2, './t (2).jpeg')

*________________________________________________________________________________创建模板
*1.选择多个区域 创建模板

* gen_rectangle1 (ROI_0, 77.6448, 748.206, 135.871, 808.124)
* gen_rectangle1 (TMP_Region, 201.539, 30.3377, 258.802, 86.9899)
* union2 (ROI_0, TMP_Region, ROI_0)
* gen_rectangle1 (TMP_Region, 202.75, 120.707, 259.263, 174.863)
* union2 (ROI_0, TMP_Region, ROI_0)
* gen_rectangle1 (TMP_Region, 81.0772, 1110.66, 135.877, 1166.35)
* union2 (ROI_0, TMP_Region, ROI_0)
* gen_rectangle1 (TMP_Region, 445.627, 569.19, 502.555, 625.771)
* union2 (ROI_0, TMP_Region, ROI_0)

*利用halcon内部的画轴平行矩形 框选了5个英雄
*岛屿分割

* connection (ROI_0, ConnectedRegions)
*计数一下
* count_obj (ConnectedRegions, Number)
* for Index1 := 1 to Number by 1
*图元变量游标从1 开始
* select_obj (ConnectedRegions, ObjectSelected,Index1)

*缩小区域

* reduce_domain (T2, ObjectSelected, ImageReduced)

*清屏显示

* dev_clear_window ()
* dev_display (ImageReduced)
*2.自动创建形状模板
*如果你需要创建的模板区域 在-10~10 生效 。你需要在创建的时候输入一个 -10~ -10*-2=20
* create_shape_model (ImageReduced, 'auto', rad(-10), rad(20),\
'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)

*3.模板的本地化存储

* write_shape_model (ModelID, './多模板库/'+Index1+'.shm')
* endfor

stop()



*________________________________________________________________________________寻找模板
*遍历模板库文件夹
list_files ('./多模板库/', 'files', Files)
*模板数组
Models:=[]

*循环读取模板到一个模板的数组里面
for Index1 := 0 to |Files|-1 by 1
*4.读取本地化存储的模板
read_shape_model (Files[Index1], ModelID)
Models[|Models|]:=ModelID
*另一种数组添加元素的写法

* Models := [Models,ModelID]
* stop()
endfor
stop()



*寻找模板 (-10 到20度角度测试)
for Index := -10 to 20 by 1
*创建一个新的图元变量数组 用来存储变换后的轮廓
gen_empty_obj (lunkuo)
rotate_image (T2, ImageRotate, Index, 'constant')
find_shape_models (ImageRotate, Models, rad(-10), rad(20), 0.5, 0, 0.5,\
'least_squares', 4, 0.9, Row, Column, Angle, Score,ModelIdx)


*判断 Row,column,angle,score中的任意一个 控制变量 看他为不为空或者数量是否大于1
if(|Row|>0)


for Index2 := 0 to |Row|-1 by 1

currentIdx:= ModelIdx[Index2]

*拿到模板的轮廓
get_shape_model_contours (ModelContours, Models[currentIdx], 1)


*根据起点到终点的状态 创建一个仿射变换的关系 刚体变换
vector_angle_to_rigid (0, 0, 0, Row[Index2], Column[Index2], Angle[Index2], HomMat2D)
*应用变换关系 把模板的轮廓xld 转到新的地方去
affine_trans_contour_xld (ModelContours, ContoursAffineTrans, HomMat2D)
dev_set_line_width (5)
dev_set_color ('red')

* dev_clear_window ()
* dev_display (ImageRotate)
* dev_display (ContoursAffineTrans)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 26, 'sans', 'true', 'false')
*$'.2f 取小数点后两位
disp_message (WindowHandle, Score[Index2]$'.2f'+' 分', 'Image', Row[Index2], Column[Index2], 'lime green', 'false')
*将找到的轮廓添加到 轮廓图元数组里面
concat_obj (lunkuo, ContoursAffineTrans, lunkuo)
dev_set_color ('yellow')
* dev_display (ImageRotate)
dev_display (lunkuo)
* stop()
endfor
dev_set_color ('red')
endif
stop()
endfor

dev_set_color ('yellow')
dev_display (ImageRotate)
dev_display (lunkuo)

额外的一些比较重要的地方

设置模板的中心参考位置,我们默认创建好了模板区域,其模板中心就是画的那个模板区域的中心/重心。 我们使用aera_center(area,row,col)来得到。 如果说有些项目我们创建模板在别的位置,但是寻找模板后要反馈一个其他的位置。这个时候就需要在创建模板后,拿到ModelID,然后对其设置模板中心的偏移。 deltaX,deltaY。 再调用halcon的 * set_shape_model_origin (ModelID, 新的点位Row-模板中心点Row, 新的点位Col-模板中心点Col) 再保存到本地。

模板的存储

1.保存模板 write_shapemodel() 保存的文件名.shm

2.保存控制变量到本地 write_tuple()

3.读取模板 read_shapelmodel()

4.读取控制变量 read_tuple()

模板匹配-NccModel(相关性模板)

介绍

相关性模板在halcon里面又叫做NCC模板。 使用于光照变幻很复杂的图片或者场景下。跟shapelModel 不一样的是 ,形状模板创建出来 是有轮廓特征的 ,这种轮廓的图元变量我们在halcon中叫做 XLD(轮廓线)。 但是NCC模板在创建的过程中是不会产生轮廓的!产生的是一个模板的区域 Region(图元变量)

使用方法:

1.导入图片

2.选择一个被测物,画一个搜索区域框中这个被测物。

3.缩小区域,只让被框中的被测物显示

4.创建NCCModel

5.保存NCCModel 至本地

6.一旦模板被创建后,就不再需要创建的过程代码了

7.从本地读取NCCModel

8.寻找模板

9.如果说找到了模板,则从Model中获取区域region,变换到找到的被测物的身上。

10.结束

算子分析:

1
2
3
4
5
6
7
8
9
*开始创建NCC 灰度模板
*1.模板特征图片
*2.金字塔级数
*3.起始旋转角度
*4.终点旋转角度的范围
*5.搜索步长
*6.极性
*7.输出模板的句柄ID
create_ncc_model (ImageReduced, 'auto', 0, 0, 'auto', 'use_polarity', ModelID)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*寻找灰度模板
*1.输入原图
*2.输入模板的句柄
*3.旋转的起点
*4.终点旋转角度的范围
*5.合格分
*6.寻找几个
*7.重叠度
*8.是否亚像素精度查找 'true' ,'false'
*9.金字塔级数
*10.输出Row
*11.输出Col
*12.输出角度
*13.输出目标得分
find_ncc_model (Image, ModelID, 0, 0, 0.5, 1, 0.5, 'true', 0, Row, Column, Angle, Score)
Rows := [Rows,Row]
Cols := [Cols,Column]
dev_display (Image)
*halcon自己封了个 显示方法
dev_display_ncc_matching_results (ModelID, 'green', Row, Column, Angle, 0)

image-20250312102936262

额外的一些比较重要的地方:

1.NCC模板是没有轮廓信息的

2.我们在进行找到的区域套到新的目标上 使用的方式就和之前不太一样咯

1
2
3
4
*拿到NCC模板的区域 
get_ncc_model_region (ModelRegion, ModelID[Index])
*区域 转 xld
gen_contour_region_xld (ModelRegion, ModelContours, 'border_holes')

3.halcon 有 2大对象 一个是控制变量,一个是图元变量(特别注意 这个图元变量里面 有 region和xld 之分)

4.region 可以转换成xld gen_contour_region_xld()

5.xld也可以转换成region gen_region_contour_xld()

6.控制变量游标从0开始,图元变量游标从1开始

模板的存储NccModel

1.write_ncc_model () *保存NCC 相关性模板

2.read_ncc_model() *从 本地读取Ncc相关性模板

模板匹配-Scaled_Shape_Model(等比例缩放模板)

介绍:

halcon的等比例缩放模板,适用在目标横方向,与纵方向等比例变大或者变小的情况。它也会和shapelModel一样产生模板轮廓xld,放置在图像坐标系的原点位置 即(0,0)。这里我们要注意 观察模板与接下来的识别对象的 最小外接矩形的宽高比值。比方说 1个像素点的宽度进行建模,寻找模板是0.5像素的目标。则最小缩放比例为 0.5/1=0.5倍。 如果说目标是放大的5倍,则在创建模板及寻找模板的时候那个最大的缩放比例系数应该填为 5/1=5倍 所以 ScaleR=ScaleC 我们称作等比例模板。 所以填入的 两个值为(0.5~5)

使用方式:

1.导入图片

2.选择一个被测物,画一个搜索区域框中这个被测物。

3.缩小区域,只让被框中的被测物显示

4.创建Scaled_Shapel_Model

5.保存Scaled_ShapeModel 至本地

6.一旦模板被创建后,就不再需要创建的过程代码了

7.从本地读取Scaled_ShapelModel

8.寻找模板

9.如果说找到了模板,则从Model中获取轮廓,变换到找到的被测物的身上。

10.结束

算子分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
*创建等比例缩放模板
*1.输入模板图片
*2.金字塔级数 NumLevels越大,找到匹配使用的时间就越小。另外必须保证最高层的图像具有足够的信息(至少四个点)。可以通过inspect_shape_model函数查看设置的结果。如果最高层金字塔的消息太少,算法内部会自动减少金字塔层数,如果最底层金字塔的信息太少,函数就会报错。如果设为auto,算法会自动计算金字塔的层数,我们可以通过get_shape_model_params函数查看金字塔的层数。如果金字塔的层数太大,模板不容易识别出来,这是需要将find_shape_model函数中MinScore和Greediness参数设置的低一些。如果金字塔层数太少找到模板的时间会增加。可以先使用inspect_shape_model函数的输出结果来选择一个较好的金字塔层数。
*3.检测角度起点
*4.捡测终点的范围角度 需要在起点角度上加上这个值 得到最终的角度(-45+90=45)
*5.ScaleMin 最下的缩放比例
*6.ScaleMax 最大的缩放比例
*7 ScaleStep 缩放比例的步长(0.77 ~5 )0.1 0.77,0.87 0.97 1.07 ('auto')
*8.是否亚像素精度搜索 对于特别大的模板图像,将参数Optimization设置为不同于'none'的其他数值是非常有用的。如果Optimization= 'none', 所有的模型点将要存储。在其他情况下, 按照Optimization的数值会将模型的点数减少. 如果模型点数变少了,必须在find_shape_model函数中将参数Greediness设为一个比较小的值, 比如:0.7、0.8。对于比较小的模型, 减少模型点数并不能提高搜索速度,因为这种情况下通常显着更多的潜在情况的模型必须进行检查。如果Optimization设置为'auto', create_shape_model自动确定模型的点数
*9.极性
*10.灰度值 参数Contras决定着模型点的对比度。对比度是用来测量目标与背景之间和目标不同部分之间局部的灰度值差异。Contrast的选择应该确保模板中的主要特征用于模型中。Contrast也可以是两个数值,这时模板使用近似edges_image函数中滞后阈值的算法进行分割。这里第一个数值是比较低的阈值,第二个数值是比较高的阈值。Contrast也可以包含第三个,这个数值是在基于组件尺寸选择重要模型组件时所设置的阈值,比如,比指定的最小尺寸的点数还少的组件将被抑制。这个最小尺寸的阈值会在每相邻的金字塔层之间除以2。如果一个小的模型组件被抑制,但是不使用滞后阈值,然而在Contrast中必须指定三个数值,在这种情况下前两个数值设置成相同的数值。这个参数的设置可以在inspect_shape_model函数中查看效果。如果Contrast设置为'auto',create_shape_model将 会自动确定三个上面描述的数值。或者仅仅自动设置对比度('auto_contrast'),滞后阈值('auto_contrast_hyst')或是 最小尺寸('auto_min_size')中一个。其他没有自动设置的数值可以按照上面的格式再进行设置。可以允许各种组合,例如:如果设置 ['auto_contrast','auto_min_size'],对比度和最小尺寸自动确定;如果设置 ['auto_min_size',20,30],最小尺寸会自动设定,而滞后阈值被设为20和30。有时候可能对比度阈值自动设置的结果是不满意的,例 如,由于一些具体应用的原因当某一个模型组件是被包含或是被抑制时,或是目标包含几种不同的对比度时,手动设置这些参数效果会更好。因此对比度阈值可以使 用determine_shape_model_params函数自动确定,也可以在调用create_shape_model之前使用inspect_shape_mode函数检查效果
*11.最小灰度值
*12.输出一个模板的句柄
create_scaled_shape_model (ImageReduced, 5, rad(-45), rad(90), 'auto', 0.8, 1.0, 'auto', 'none', 'ignore_global_polarity', 40, 10, ModelID)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
*1.原图
*2.模板ID 句柄
*3.寻找的起始角度
*4.寻找的终点范围 也就是45度
*5.最小缩放比例
*6.最大缩放比例
*7.合格分
*8.找多少个
*9.重叠度
*10.是否亚像素精度查找
*11.金字塔级数
*12.贪婪度
*13.找到的目标Row
*14.找到的目标Col
*15.找到的目标Angle
*16.找到的目标缩放比例
*17.找到的目标的分数
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)
*因为找的目标有3个 所以要循环来把在左边原点 0,0的轮廓 分别变换到各自的位置吧
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)
*使用关系
affine_trans_contour_xld (Model, ModelTrans, HomMat2DScale)
dev_display (ModelTrans)
endfor

额外的一些比较重要的地方:

这种等比例缩放模板,如果寻找不到,你需要调整 1.合格分2.缩放系数3.取消亚像素精度搜索4.贪婪度加大 5.金字塔级数加大

模板的存储与恢复:

1.write_shape_model(模板的ID,存放的路径 ‘.shm’) 等比例缩放模板其实是形状模板的一份子。所以保存依旧采用与ShapelModel一样的方式。

2.read_shape_model(路径,传出一个模板的ID)

模板匹配-Aniso_Shape_Model(各向异性模板、不等比例缩放模板)

介绍:

这个形状模板叫做各个方向形变量不一样的,就是横,纵方向形变比例不一样。叫做各向异性模板或者叫不等比例缩放模板。这个算子和Scaled_shape_model 有啥差异? 等比例缩放模板 横纵缩放比例一样,用两个控制变量搞定(ScaleRow,ScaleColumn) 那么Aniso_shapl_model(由 ScaleRowMin,ScaleRowMax,ScaleColMin,ScaleMax)

使用方式

1.导入图片

2.选择一个被测物,画一个搜索区域框中这个被测物。

3.缩小区域,只让被框中的物体显示

4.创建Aniso_Shapel_Model

5.保存Aniso_ShapeModel 至本地

6.一旦模板被创建后,就不再需要创建的过程代码了

7.从本地读取Aniso_ShapelModel

8.寻找模板

9.如果说找到了模板,则从Model中获取轮廓,变换到找到的被测物的身上。

10.结束

算子分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*创建各向异性模板
*1.原图
*2.金字塔
*3.起始角度
*4.终点区域 0-360
*5.旋转步距
*6.row方向的缩放最小值
*7.row方向的缩放最大值
*8.row方向的缩放步长
*9.col方向的缩放最小值
*10.col方向的缩放最大值
*11.col方向的缩放步长
*12,忽略的颜色的极性
*13.对比度
*14.最小对比度
*15.输出模板
create_aniso_shape_model (Image, 5, rad(0), rad(360), 'auto', 0.7, 1.3, 'auto', 1, 1,\
'auto', 'auto', 'ignore_color_polarity', 'auto', 'auto', ModelID1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
*1.被搜索的原图
*2.带入模板的ID 这里是多模板数组
*3.搜索起点
*4.搜索范围
*5.纵向最小缩放
*6.纵向最大缩放
*7.横向最小缩放
*8.横向最大缩放
*9.合格分
*10.找多少个模板
*11.重叠度
*12.最小亚像素精度搜索?
*13.金字塔级数
*14.贪婪度
*15.输出找到的Row
*16.输出找到的Col
*17.输出找到的Angle
*18.输出找到的ScaleR 纵向比例
*19.输出找到的ScaleC 横向拉伸比例
*20.多模板会多一个 模板句柄的ID
find_aniso_shape_models (Image, [ModelID1,ModelID2], rad(0), rad(360), 0.7, 1.3, 1,\
1, 0.80, 1, 0.5, 'least_squares', 0, 0.80, Row, Column, Angle, ScaleR, ScaleC, Score, Model)

额外的一些比较重要的地方

模板的存储与恢复

1.write_shape_model(模板的ID,存放的路径 ‘.shm’) 等比例缩放模板其实是形状模板的一份子。所以保存依旧采用与ShapelModel一样的方式。

2.read_shape_model(路径,传出一个模板的ID)

模板匹配-Generic _Shape_Model(通用形状模板)

介绍:

通用形状模板,可以让你自己创建一个轮廓线xld。比方我创建一个圆角矩形,然后生成一张图片,把圆角矩形xld 内部填充掉,在使用 通用形状模板创建。 这里需要注意一下 圆角矩形的 长度和宽度 必须要结合实际。实际物体的最小外接矩形 是多少像素点,需要你自己来记录一下,然后再虚拟的创建一个包围的多边形。

使用方式:

1.导入图片

2.根据实物拍摄的长度和宽度像素,虚拟创建一个圆角多边形封闭区域,然后喷涂在一个新的图片上。

3.创建create_generic_shape_model (ModelID)

4.设置通用形状模板的参数

5.训练通用形状模板

5.保存ShapeModel 至本地

6.一旦模板被创建后,就不再需要创建的过程代码了

7.从本地读取ShapelModel

8.寻找模板

9.如果说找到了模板,则通过 get_generic_shape_model_result_object (Objects, MatchResultID, ‘all’, ‘contours’)获取轮廓就直接在被测目标的身上了。

10.结束

算子分析:

  • ```
    • Create a synthetic model for the SMD capacitors.
    • This is just a rectangle with rounded corners.
      *创建一个封闭的 圆角多边形轮廓线
      *我来一次性 生成一个 数组 包含同一个数值
      tuple_gen_const (5, 6, yj)
      gen_contour_polygon_rounded_xld (Contour, [50, 100, 100, 50, 50], [50, 50, 150, 150, 50],
      yj, 1)
      *生成一张图片 200x150
      gen_image_const (Image, ‘byte’, 200, 150)
      *上午说的 把轮廓线的内部直接填充灰度
      paint_xld (Contour, Image, ImageModel, 128)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28

      * ```
      * * Create a generic shape model with anisotropic scaling.
      *"anisotropic scaling" 可以翻译为 "各向异性缩放"。
      *在图像处理或计算机图形学中,各向异性缩放指的是在不同方向上(例如水平和垂直方向)以不同的比例进行缩放,而不是均匀地缩放整个对象
      *创建一个通用形状模板
      create_generic_shape_model (ModelID)
      *设置通用形状模板的参数
      set_generic_shape_model_param (ModelID, 'scale_row_min', 0.9)
      set_generic_shape_model_param (ModelID, 'scale_row_max', 1.7)
      set_generic_shape_model_param (ModelID, 'scale_column_min', 0.9)
      set_generic_shape_model_param (ModelID, 'scale_column_max', 1.1)
      set_generic_shape_model_param (ModelID, 'num_levels', 0)
      *训练一下 通用形状模板
      train_generic_shape_model (ImageModel, ModelID)
      *拿到通用形状模板的 轮廓线 丢在 0,0,原点处
      get_generic_shape_model_object (ModelContours, ModelID, 'contours')
      *
      * 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
      * 在图像中查找SMD电容器的模型
      * 并显示找到的模型数量、识别时间以及模型的缩放比例
      set_generic_shape_model_param (ModelID, 'min_score', 0.7)
      set_generic_shape_model_param (ModelID, 'angle_start', rad(-10))
      set_generic_shape_model_param (ModelID, 'angle_end', rad(10))

      ### 额外的一些比较重要的地方

模板的存储与恢复

1.write_shape_model(模板的ID,存放的路径 ‘.shm’) 等比例缩放模板其实是形状模板的一份子。所以保存依旧采用与ShapelModel一样的方式。

2.read_shape_model(路径,传出一个模板的ID)

模板匹配-local_deformable_Model(局部可变形模板)

介绍:

使用方式

算子分析

额外的一些比较重要的地方

模板的存储与恢复

模板匹配-deformable_Model(变形模板)

介绍:

使用方式

算子分析

额外的一些比较重要的地方

模板的存储与恢复

模板匹配-Points_Model(基于点的模板)

介绍:

使用方式

算子分析

额外的一些比较重要的地方

模板的存储与恢复

模板匹配-Variation_Model(质量检测模板、对比模板)

介绍:

使用方式

算子分析

额外的一些比较重要的地方

模板的存储与恢复

仿射变换

介绍:

仿射变换是一种结合线性变换与平移的几何变换方法,能够描述旋转、缩放、平移等多种操作,同时保持几何结构的特定属性。它在计算机图形学、机器视觉等领域具有广泛的实际价值。下文将从数学定义、核心性质、齐次坐标表示以及应用场景四个方面展开说明

右脑图像记忆:

在halcon中的通过单位矩阵叠加的写法:

1
2
3
4
5
6
7
8
9
10
*创建一个单位矩阵
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)
*使用关系
affine_trans_contour_xld (Model, ModelTrans, HomMat2DScale)

在halcon中的通过刚体变幻的写法:

1
2
3
4
*通过一个起点的坐标+弧度 和一个终点坐标+弧度 可以直接一句话得到一个映射关系 homat2d.但是这种方式没法带入缩放关系
Vector_angle_to_rigid(0,0,0,row,col,angle,homat2d);
*添加一个缩放关系就完了
hom_mat2d_scale (homat2d, Scale, Scale,row, col, HomMat2DScale)