*这个示例程序演示了如何使用HALCON的基于形状的匹配,在一次调用中查找多个不同的模型以查找_shape_模型。请注意是一种经常有用的操作模式。
多模板匹配例程
*在程序执行期间关闭电脑的更新。
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]
*对象模型将包含一组表示不同模型的XLD轮廓。它们在下面用于在当前图像上覆盖找到的模型。
*使用XLD轮廓是因为它们可以更快地变换而不是地区。这会产生一个小问题,因为通常有多个XLD
*等高线将代表一个模型。因此不同的模型将分别存储在IndexS和IndexE中。
*设置一个空数组
gen_empty_obj (Models)
IndexS := []
IndexE := []
*变量ModelIDs包含下面创建的不同模型。
ModelIDs := []
*同样,RowsRef和ColumnsRef存储不同模型的参考点。
*它们是将模型转换为当前图像中找到的实例所必需的。
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)
*形成不同的连通域
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)
*计算当前模型和模型中有多少XLD轮廓已存储的模型。这是计算Index和IndexE所必需的。
*Models上面先定义了为空
count_obj (ModelContours, NumModel)
*计算现容器有的轮廓
count_obj (Models, NumModels)
*类似建立一个容器,把控件的轮廓放进去
concat_obj (Models, ModelContours, Models)
*
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)
*注意和这个是models
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
**从模型对象中选择正确的XLD轮廓。
*复制HALCON数据库中的图标对象。
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$'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
for J := 0 to |ModelIDs| - 1 by 1
clear_shape_model (ModelIDs[J])
endfor