机器视觉模板匹配,halcon示例讲解,入门篇
基于灰度值模板
基于形状(最常用的。受光照有一定影响)
//使用ROI区域绘制模板。使用blob分析创建模板。使用CAD导入轮廓创建模板
//一对多。多对多。
基于相关性(不受光照的影响,不受变焦影响)
基于灰度值(几乎不用,受光照影响很大)
基于局部变形
基于组件
基于描述符号
基于相关性匹配
Halcon例程
例程一:方法-》模板匹配 ->find_ncc_model_exposure.hdev
详细描述:Find an object despite linear illumination change using correlation-baked matching
代码:
//读图
read_image (Image, ‘cap_exposure/cap_exposure_03’)
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, ‘mono’, ‘true’, ‘false’)
dev_update_off ()
//预处理
gen_circle (Circle, 246, 336, 150)
//选择瓶盖所在的圆形区域
area_center (Circle, Area, RowRef, ColumnRef)
//求取中心面积
reduce_domain (Image, Circle, ImageReduced)
//裁剪
create_ncc_model (ImageReduced, ‘auto’, 0, 0, ‘auto’, ‘use_polarity’, ModelID)
//创建模型。ImageReduced:输入图像。‘auto’:金字塔图像层数(自动)。0:最小旋转角度。0:最大旋转范围。‘auto’:旋转角度的步长(自动)。‘use_polarity’:匹配标准(极性匹配)。ModelID:模型句柄
dev_set_draw (‘margin’)
dev_display (Image)
dev_set_color (‘yellow’)
dev_display (Circle)
disp_message (WindowHandle, ‘Trained NCC model’, ‘window’, 12, 12, ‘black’, ‘true’)
disp_continue_message (WindowHandle, ‘black’, ‘true’)
stop ()
Rows := []
Cols := []
//查找
for J := 1 to 10 by 1
read_image (Image, ‘cap_exposure/cap_exposure_’ + J$‘02’)
//读取图像路径。
find_ncc_model (Image, ModelID, 0, 0, 0.5, 1, 0.5, ‘true’, 0, Row, Column, Angle, Score)
//相关性匹配。光照不均匀,亮暗变化,但是背景不能复杂
// Image:输入图像。ModelID:模板句柄。0, 0:最小旋转角度,旋转角度范围。0.5:匹配性分数。1:寻找模板最大个数(0为全都找)。0.5:重叠度。‘true’:是否采用亚像素精度。0:使用的金字塔层数(越多搜索越快,准确度下降)。Row,Column,Angle:物体的行列坐标旋转角度。Score:精度分数。
//显示
Rows := [Rows,Row]
Cols := [Cols,Column]
dev_display (Image)
dev_display_ncc_matching_results (ModelID, ‘green’, Row, Column, Angle, 0)
disp_message (WindowHandle, ‘Found NCC model’, ‘window’, 12, 12, ‘black’, ‘true’)
if (J < 10)
disp_continue_message (WindowHandle, ‘black’, ‘true’)
endif
stop ()
endfor
StdDevRows := deviation(Rows)
StdDevCols := deviation(Cols)
基于形状匹配
Halcon例程
(一对多)
例程二:方法-》模板匹配(基于形状) ->find_scaled _shape_model.hdev
详细描述:find object using shape-base matching(with scaling and rotation). 使用形状基础匹配(缩放和旋转)查找对象。
代码:
- 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)
//blob分析抠图
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)
//创建模板。
//scaled:带缩放
// 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)
//对模板进行匹配
//scaled:支持缩放
// 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)
affine_trans_contour_xld (Model, ModelTrans, HomMat2DScale)
dev_display (ModelTrans)
endfor
Halcon例程
(一对多)
例程三:方法-》模板匹配(基于形状) ->create_roi_viavvision.hdev
详细描述:create a shape models from XLD contours (从XLD等高线创建形状模型)
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 () - ------------------- start of the application ----------------
- step 1: extract the bright regions
//blob分析抠图
threshold (ModelImage, BrightRegions, 200, 255)
connection (BrightRegions, ConnectedRegions)
fill_up (ConnectedRegions, FilledRegions)
dev_display (ModelImage)
dev_display (FilledRegions)
stop () - step 2: select the region of the card
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)
//放大图像。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 () - step 3: use the card as an ROI for the next steps
reduce_domain (ModelImage, Card, ImageCard)
//裁剪区域
stop () - step 4: extract the logo
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 () - step 5: enlarge the region slightly
dilation_circle (CharacterRegion, ROI, 1.5)
dev_display (ModelImage)
dev_display (ROI)
stop () - step 6: creating the model
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)
//多个可以使用的匹配模板,用于检查那个模板好用。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 () - step 7: searching the logo
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)
相关例子:(一对多)
find_aniso_shape_model.hdev(寻找大小不等相似的图像)
Find_cocoa_packages_max(对整幅图创建模板)
Inspect_shampoo_label.hdev(创建多个模板【一对多】)
Reuse_model.hdev(写入模板文件,读取模板文件)
Synthetic_circle.hdev(形成轮廓并以轮廓为模板)
Pm_measure_board.hdev(使用模板匹配后进行测量)
Halcon例程
(多对多)
例程四:方法-》模板匹配(基于形状) ->pm_multiple_models.hdev
详细描述:find multiple different models in a single pass using shape-based matching
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)
Colors := [‘red’,‘green’,‘cyan’]
Row1 := [135,150,185]
Column1 := [250,170,220]
Row2 := [375,310,335]
Column2 := [355,395,375]
gen_empty_obj (Models)
//形成空的区域数组
IndexS := []
IndexE := []
ModelIDs := []
//创建模板。
for J := 1 to 3 by 1
read_image (Image, ‘metal-parts/metal-part-model-’ + J
′
02
d
′
)
/
/
读
图
d
e
v
d
i
s
p
l
a
y
(
I
m
a
g
e
)
d
e
v
s
e
t
c
o
l
o
r
(
′
g
r
e
e
n
′
)
/
/
显
示
图
像
s
e
t
t
p
o
s
i
t
i
o
n
(
W
i
n
d
o
w
H
a
n
d
l
e
,
20
,
20
)
w
r
i
t
e
s
t
r
i
n
g
(
W
i
n
d
o
w
H
a
n
d
l
e
,
′
G
e
n
e
r
a
t
i
n
g
s
h
a
p
e
m
o
d
e
l
′
+
J
'02d') //读图 dev_display (Image) dev_set_color ('green') //显示图像 set_tposition (WindowHandle, 20, 20) write_string (WindowHandle, 'Generating shape model ' + J
′02d′)//读图devdisplay(Image)devsetcolor(′green′)//显示图像settposition(WindowHandle,20,20)writestring(WindowHandle,′Generatingshapemodel′+J’d’)
//显示字符位置
gen_rectangle1 (Rectangle, Row1[J - 1], Column1[J - 1], Row2[J - 1], Column2[J - 1])
//绘制ROI区域
area_center (Rectangle, Area, Row, Column)
//或者中心角度
reduce_domain (Image, Rectangle, ImageReduced)
//裁剪
inspect_shape_model (Image, ModelImages, ModelRegions, 1, 30)
//检测模板特性
connection (ModelRegions, ConnectedRegions)
//断开
select_shape (ConnectedRegions, SelectedRegions, ‘area’, ‘and’, 20, 100000)
//特征选择
union1 (SelectedRegions, ModelRegions)
//联合连通域
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_obj (ModelContours, NumModel)
//计算轮廓数量
count_obj (Models, NumModels)
//计算连通域个数
concat_obj (Models, ModelContours, Models)
//将所有轮廓装入一个空model中
IndexS := [IndexS,NumModels + 1]
IndexE := [IndexE,NumModels + NumModel]
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 (Image, ModelIDs, rad(0), rad(360), 0.5, 0, 0.5, ‘least_squares’, 0, 0.8, Row, Column, Angle, Score, Model)
// find_shape_models多对多模板查找。
count_seconds (S2)
Time := (S2 - S1) * 1000
dev_display (Image)
Num := |Score|
for J := 0 to Num - 1 by 1
//显示
copy_obj (Models, ModelSelected, IndexS[Model[J]], IndexE[Model[J]] - IndexS[Model[J]] + 1)
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
′
1
d
′
+
′
o
b
j
e
c
t
f
o
u
n
d
i
n
′
+
T
i
m
e
'1d' + ' object found in ' + Time
′1d′+′objectfoundin′+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
相关例程:(多对多)
Pm_mulitiple_dxf_models(直接读取模板)
write_shape_model(ModelID,’dot.shm’)
//将模板写入并保存为文件
Read_shape_model(’dot.shm’,ModelID2)
//读取模板文件,应用到ModelID2句柄
总结:入门篇总共列举了,基于相关性的模板匹配和基于形状的模板匹配,其中基于形状的模板匹配中一对多和多对多的情况。直接学习halcon的例程内容方便我们直接学习。
基于形状(最常用的。受光照有一定影响)
使用ROI区域绘制模板。使用blob分析创建模板。使用CAD导入轮廓创建模板
基于相关性(不受光照的影响,但是受图像大小等多种因素影响)