对应示例程序:
measure_fill_level.hdev
目标:检查每个单滴鼻安瓿的灌装水平,制药行业的填充级别检查。
思路为:
1.读取图像
2.创建定位模板图像
3.利用基于形状的匹配来定位每个安瓿头
4.利用measure_pos计算液体的实际位置,根据容忍度进行产品的归类
图像:
代码:
dev_close_window ()
dev_update_off ()
read_image (Image, 'ampoules/ampoules_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_line_width (2)
dev_set_draw ('margin')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
*
* Create a model for the ampoule head to align the measure handle 创建模板
gen_rectangle1 (Rectangle, 230, 280, 317, 330)
reduce_domain (Image, Rectangle, ImageModel)
create_shape_model (ImageModel, 'auto', 0, 0, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
*
* Initialize the measure handle 测量参数初始化
gen_measure_rectangle2 (0, 0, rad(90), 75, 20, Width, Height, 'bilinear', MeasureHandle)
gen_rectangle2 (rr,0, 0, rad(90), 75, 20) //显示测量矩形
Tolerance := 15
*
* Determine the fill level
NumImages := 8
for Index := 1 to NumImages by 1
read_image (Image, 'ampoules/ampoules_' + Index$'.2d')
ColumnEdges := []
FillLevelHeight := []
*
find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0.1, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
gen_rectangle1 (Rectangle1, Row, Column, Row+10, Column+10) //简单显示匹配结果
MeanRow := mean(Row) //求Row均值
RefLevel := MeanRow - 160 //根据先验知识 生成后面的标准位置矩形
* Display tolerance area
dev_display (Image)
dev_set_line_width (1)
dev_set_color ('white')
gen_rectangle2 (AcceptLevel, RefLevel, mean(Column), 0, 30 + (max(Column) - min(Column)) / 2, Tolerance) //先验知识生成的标准位置矩形
dev_display (AcceptLevel)
dev_set_line_width (2)
*
* Determine fill level of each ampoule
Errors := 0
for Idx := 0 to |Score| - 1 by 1
translate_measure (MeasureHandle, MeanRow - 135, Column[Idx]) //移动测量矩形到某个位置
gen_rectangle2 (rrr,MeanRow - 135, Column[Idx], rad(90), 75, 20) //显示测量矩形
* Search for the topmost edge
measure_pos (Image, MeasureHandle, 2, 7, 'all', 'first', RowEdge, ColumnEdge, Amplitude, Distance) //测量垂直于矩形的边缘点以及相关参数
FillLevelHeight := [FillLevelHeight,RowEdge] //收集中心边缘点的行坐标
ColumnEdges := [ColumnEdges,ColumnEdge] //收集中心边缘点的列坐标
gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 15, 0) //生成一个十字
gen_rectangle2 (FillLevel, RowEdge, ColumnEdge, 0, 28, 20) //用一个矩形块显示液体边缘的位置
if (abs(FillLevelHeight[Idx] - RefLevel) >= Tolerance) //(如果液体中心点的行坐标 - 先验知识中液体的标准行坐标) > 容忍度
gen_rectangle2 (ChamberSingle, MeanRow - 133, Column[Idx], 0, 35, 90)
gen_cross_contour_xld (Cross, FillLevelHeight[Idx], ColumnEdges[Idx], 15, 0)
gen_rectangle2 (FillLevel, FillLevelHeight[Idx], ColumnEdges[Idx], 0, 28, 20)
Errors := Errors + 1
dev_set_color ('red')
dev_display (ChamberSingle) //显示一个大的矩形块
disp_message (WindowHandle, 'NG', 'image', FillLevelHeight[Idx] - 50, ColumnEdges[Idx] - 10, 'red', 'false')
else
disp_message (WindowHandle, 'OK', 'image', FillLevelHeight[Idx] - 50, ColumnEdges[Idx] - 10, 'green', 'false')
dev_set_color ('green')
endif
dev_display (FillLevel)
dev_display (Cross)
endfor
*
* Check, whether the fill level is within the allowed range - does not deviate too much
* from average fill level
*
* Display statistics 结果统计显示
if (Errors > 0)
disp_message (WindowHandle, Errors + ' BAD', 'window', 10, 12, 'red', 'true')
else
disp_message (WindowHandle, 'All OK', 'window', 10, 12, 'forest green', 'true')
endif
if (Index < NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
*
close_measure (MeasureHandle)
clear_shape_model (ModelID)
用到的几个算子:
create_shape_model–创建形状匹配模板(句柄)
find_shape_model–执行形状匹配
clear_shape_model–清除形状匹配模板
gen_measure_rectangle2–生产测量参数句柄
translate_measure–调整测量矩形的位置
measure_pos–提取垂直于矩形或环形弧的直边,和相关参数