对应示例程序:
inspect_shampoo_label.hdev
目标:定位洗发水瓶子上的标签位置
思路为:
1.读取图像
2.创建瓶子的模板图像
3.创建标签的模板图像
4.进行形状匹配,如果上述两个模板匹配的结果在合理的范围内,就认为匹配成功
图像:
代码:
dev_update_off ()
dev_set_draw ('margin')
dev_set_line_width (2)
*
* load reference image for model preparation
set_system ('clip_region', 'false')
read_image (Image, 'packaging/shampoo_01')
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_display (Image)
*
* prepare the shape model for matching
*
* generate first model region and search ROI
BottleModelRow := 131
BottleModelColumn := 370
BottleModelLength1 := 350
BottleModelLength2 := 35
BottleModelPhi := -0.1093
*生成感兴趣区域
gen_rectangle2 (Rectangle1, BottleModelRow, BottleModelColumn, BottleModelPhi, BottleModelLength1, BottleModelLength2)
gen_rectangle2 (Rectangle2, BottleModelRow + 220, BottleModelColumn, -BottleModelPhi, BottleModelLength1, BottleModelLength2)
union2 (Rectangle1, Rectangle2, TemplateBottleRegion)
get_domain (Image, Domain) //获取图像的范围
intersection (TemplateBottleRegion, Domain, TemplateBottleRegion) //求交集 防止上面的ROI超出图像区域
area_center (TemplateBottleRegion, Area, RowBottleRef, ColumnBottleRef)
gen_circle (SearchROIBottle, RowBottleRef, ColumnBottleRef, 40)
reduce_domain (Image, TemplateBottleRegion, ImageReduced) //裁剪出的上下两部分ROI
*
* create shape model 创建瓶子模板图像
create_shape_model (ImageReduced, 5, -rad(3), rad(6), 0, 'auto', 'use_polarity', 25, 3, ModelIDBottle)
*
* display shape model 瓶子模板图像的显示
dev_display (Image)
dev_set_color ('forest green')
dev_display (TemplateBottleRegion)
dev_set_color ('slate blue')
disp_message (WindowHandle, 'bottle shape model', 'window', -1, -1, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* generate second model region and search ROI
LabelRow1 := 180
LabelRow2 := 310
LabelColumn1 := 50
LabelColumn2 := 470
gen_rectangle1 (TemplateLabelRegion, LabelRow1, LabelColumn1, LabelRow2, LabelColumn2) //生成Label矩形区域
area_center (TemplateLabelRegion, Area1, RowLabelRef, ColumnLabelRef)//计算Label的中心
gen_circle (SearchROILabel, RowLabelRef, ColumnLabelRef, 60) //生成Label圆形
reduce_domain (Image, TemplateLabelRegion, ImageReduced)//裁剪出Label图像
inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 25) //查看形状模型
*
* create shape model 生成标签的模板图像 多个方向
create_shape_model (ImageReduced, 5, rad(-3), rad(6), 0, 'auto', 'use_polarity', 25, 5, ModelIDLabel1)
create_shape_model (ImageReduced, 5, rad(180 - 3), rad(6), 0, 'auto', 'use_polarity', 25, 5, ModelIDLabel2)
ModelIDsLabel := [ModelIDLabel1,ModelIDLabel2]
*
* display label model
dev_display (Image)
dev_set_color ('forest green')
dev_display (TemplateLabelRegion)
dev_set_color ('slate blue')
dev_display (ModelRegions)
disp_message (WindowHandle, 'create label shape model', 'window', -1, -1, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* MainLoop
*
* check relative positions of label and bottle in all images
for Index := 1 to 13 by 1
read_image (Image, 'packaging/shampoo_' + Index$'.2')
dev_display (Image)
disp_message (WindowHandle, 'check label position', 'window', -1, -1, 'black', 'true')
count_seconds (s1)
*
reduce_domain (Image, SearchROIBottle, ImageReduced)
*瓶子检测 用待测图像的圆形区域 去做形状匹配 (没理解)
find_shape_model (ImageReduced, ModelIDBottle, -rad(3), rad(6), 0.7, 1, 0.5, 'least_squares', 0, 0.9, RowBottle, ColumnBottle, AngleBottle, ScoreBottle)
* prepare search ROIs in search image 之前创建了两个形状匹配的Lablel Moedl,所以这里也要输入两个待测图像
concat_obj (SearchROILabel, SearchROILabel, SearchROIs) //连接两个图像元组
add_channels (SearchROIs, Image, GrayRegions) //向区域增加灰色值
*
* search shape models 标签检测
find_shape_models (GrayRegions, ModelIDsLabel, [rad(-3),rad(180 - 3)], [rad(6),rad(6)], 0.6, 1, 1, 'interpolation', 0, 0.9, Row, Column, Angle, Score, FoundModel)
count_seconds (s2) //用于统计消耗时间
if (|Score| != 1 or |ScoreBottle| != 1) //匹配不成功
disp_message (WindowHandle, 'Model not found', 'window', 40, -1, 'red', 'true')
else
if (ModelIDsLabel[FoundModel] == ModelIDLabel2)
disp_message (WindowHandle, 'Label rotated by 180°', 'window', 40, -1, 'red', 'true')
else
* calculate y deviation y方向的偏差 = 测量值之间的差-标准值之间的差
Diffy := (RowBottle - Row) - (RowBottleRef - RowLabelRef)
* calculate x deviation X方向的偏差 = 测量值之间的差-标准值之间的差
Diffx := (ColumnBottle - Column) - (ColumnBottleRef - ColumnLabelRef)
*
* check the rotation angle of the bottle label 旋转角度 = 两个匹配角度的差值
Diffa := deg(AngleBottle - Angle)
*
* calculate the time elapsed 消耗时间
Time := s2 - s1
*
* display results 结果显示
Color := 'black'
ModelColor := 'forest green'
if (abs(Diffx) > 3)
Color := [Color,'red']
ModelColor := 'red'
else
Color := [Color,'forest green']
endif
if (abs(Diffy) > 1)
Color := [Color,'red']
ModelColor := 'red'
else
Color := [Color,'forest green']
endif
if (abs(Diffa) > 1)
Color := [Color,'red']
ModelColor := 'red'
else
Color := [Color,'forest green']
endif
dev_display_shape_matching_results (ModelIDsLabel, ['slate blue',ModelColor], Row, Column, Angle, 1, 1, FoundModel)
disp_message (WindowHandle, ['Time = ' + (Time * 1000)$' .2' + ' ms','Diff x = ' + Diffx$' .2','Diff y = ' + Diffy$' .2','Diff angle = ' + Diffa$' .2'], 'window', 35, -1, Color, 'true')
endif
*
endif
if (Index < 13)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
else
disp_message (WindowHandle, 'Program finished', 'window', 450, 430, Color, 'true')
endif
endfor
stop ()
clear_shape_model (ModelIDLabel1)
clear_shape_model (ModelIDLabel2)
clear_shape_model (ModelIDBottle)
set_system ('clip_region', 'true')
用到的几个算子:
get_domain—获取图像的定义域
create_shape_model–创建形状匹配模板(句柄)
inspect_shape_model–查看形状匹配模板,检查参数的适用性
find_shape_model–执行形状匹配
clear_shape_model–清除形状匹配模板
参考资料:
[1]:https://blog.csdn.net/mangobar/article/details/84869364
[2]:https://blog.csdn.net/maweifei/article/details/78188993