halcon例程解析:测量生鱼条的大小——check_fish_stick_dimension
In this program the size of raw fish sticks is measured before they are coated with bread crumbs. First, the fish sticks are segmented from the background. Then, their dimensions are measured, compared to the required minimum size, and the result is displayed.
在这个项目中,生鱼条的大小是在涂上面包屑之前测量的。首先,将鱼条从背景中分割出来。然后,测量它们的尺寸,与所需的最小尺寸进行比较,并显示结果。
1. 效果展示
2. 思路分析
根据亮度信息进行阈值分割,利用面积选取有效区域,去除与图像边缘重合的部分,计算长度判断是否合格。
- 分割出鱼片区域
- 去掉被图像边缘隔断的区域
- 最小外接矩形,判断是否合格
2.1 分割出鱼片区域
* 分割出鱼片区域
threshold(Image, Region, 50, 255) //阈值分割,以50为阈值,亮区域为有效区域
connection(Region, ConnectedRegions) //连通区域分析
fill_up(ConnectedRegions, RegionFillUp) //填充区域
select_shape(RegionFillUp, SelectedRegions, 'area', 'and', 1000, 99999) //用面积来筛选有效区域
2.2 去掉被图像边缘隔断的区域
* 去掉被图像边缘隔断的区域
boundary(Image, RegionBorder, 'inner') //找到图像的边界
* 找到有效区域与边界的交集,注意交集是多维,有可能存在空区域
intersection(SelectedRegions, RegionBorder, RegionIntersection)
area_center(RegionIntersection, Area, Row1, Column1) //计算交集区域的面积、中心
* 如果交集面积为0,则该区域不与边界相交,反之则相交。[==]中的[]为元组处理,获取到的是索引
select_mask_obj(SelectedRegions, ValidSticks, Area [==] 0)
select_mask_obj(SelectedRegions, StickAtBorder, Area [!=] 0)
2.3 最小外接矩形,判断是否合格
* 最小外接矩形,判断是否合格
smallest_rectangle2(ValidSticks, Row, Column, Phi, Length1, Length2)
* 像素大小转为实际的cm单位,cm_per_pix是已经标定计算好的,*2是因为Length1为半径
FishLength1 := Length1 * 2 *cm_per_pix
* 判断是否合格,注意这里的优先级,+-优先级大于 >= 这些,实际不确定时就加小括号
Good := (FishLength1 [>=] TargetLength - ToleranceLow) and (FishLength1 [<=] TargetLength + ToleranceHigh)
Bad := not Good
3. 全部代码
* In this program the size of raw fish sticks is measured
* before they are coated with bread crumbs.
* First, the fish sticks are segmented from the background.
* Then, their dimensions are measured, compared to the
* required minimum size, and the result is displayed.
*
dev_update_off ()
dev_close_window ()
read_image (Image, 'food/fish_sticks_raw_01')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
get_system ('store_empty_region', StoreEmptyRegion)
set_system ('store_empty_region', 'true')
*
cm_per_pix := 0.0373
TargetLength := 9.0
ToleranceHigh := 0.8
ToleranceLow := 0.2
*
NumImages := 10
for I := 1 to NumImages by 1
read_image (Image, 'food/fish_sticks_raw_' + I$'.2')
*
* Segment the raw fish sticks
threshold (Image, Region, 50, 255)
connection (Region, ConnectedRegions)
fill_up (ConnectedRegions, RegionFillUp)
select_shape (RegionFillUp, SelectedRegions, 'area', 'and', 1000, 99999)
*
* Select the regions that do not intersect the image border
boundary (Image, RegionBorder, 'inner')
intersection (SelectedRegions, RegionBorder, RegionIntersection)
area_center (RegionIntersection, Area, Row1, Column1)
select_mask_obj (SelectedRegions, ValidSticks, Area [==] 0)
select_mask_obj (SelectedRegions, StickAtBorder, Area [!=] 0)
*
* Check the size of the fish sticks
smallest_rectangle2 (ValidSticks, Row, Column, Phi, Length1, Length2)
FishLength1 := Length1 * 2 * cm_per_pix
Good := (FishLength1 [>=] TargetLength - ToleranceLow) and (FishLength1 [<=] TargetLength + ToleranceHigh)
Bad := not Good
*
* Display the results
RowGood := select_mask(Row,Good)
ColumnGood := select_mask(Column,Good)
RowBad := select_mask(Row,Bad)
ColumnBad := select_mask(Column,Bad)
FishLength1Good := select_mask(FishLength1,Good)
FishLength1Bad := select_mask(FishLength1,Bad)
gen_rectangle2 (AllSticks, Row, Column, Phi, Length1, Length2)
select_mask_obj (AllSticks, GoodSticks, Good)
select_mask_obj (AllSticks, BadSticks, Bad)
*
dev_display (Image)
dev_set_color ('white')
dev_set_line_width (1)
dev_display (ValidSticks)
dev_set_line_width (3)
dev_set_color ('yellow')
dev_display (StickAtBorder)
dev_set_color ('green')
dev_display (GoodSticks)
dev_set_color ('red')
dev_display (BadSticks)
String := 'Target length: ' + TargetLength$'.1f' + ' cm'
String[1] := 'Tolerance: -' + ToleranceLow$'.1f' + '/+' + ToleranceHigh$'.1f'
disp_message (WindowHandle, String, 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'OK', 'image', 80, ColumnGood - 10, 'green', 'false')
disp_message (WindowHandle, FishLength1Good$'.1f' + 'cm', 'image', RowGood, ColumnGood - 28, 'white', 'false')
disp_message (WindowHandle, 'Not OK', 'image', 80, ColumnBad - 30, 'red', 'false')
disp_message (WindowHandle, FishLength1Bad$'.1f' + 'cm', 'image', RowBad, ColumnBad - 28, 'white', 'false')
if (I != NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
set_system ('store_empty_region', StoreEmptyRegion)