对应示例程序:
ball_seq.hdev
目标:检测和定位焊球
思路为:
1.先利用阈值分割 和 孔洞填充定位目标区域
2.利用矩形和圆形的差异 去掉矩形
3.形态学处理 得到最后的圆形孔洞
4.结果显示
图像:
代码:
dev_update_off ()
ImageNames := 'die/' + ['die_02','die_03','die_04','die_07']
dev_set_colored (12)
read_image (Bond, ImageNames[0])
get_image_size (Bond, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
NumImages := |ImageNames|
for I := 0 to NumImages - 1 by 1
read_image (Bond, ImageNames[I])
dev_display (Bond)
min_max_gray (Bond, Bond, 0, Min, Max, Range) //图像中的最大最小灰度
threshold (Bond, Bright, Max - 80, 255) //阈值分割
shape_trans (Bright, Die, 'rectangle2') //最小外接矩形
dev_display (Die)
reduce_domain (Bond, Die, DieGrey) //裁剪ROI
min_max_gray (Die, Bond, 0, Min, Max, Range) //最大最小灰度
threshold (DieGrey, Wires, 0, Min + 30) //阈值分割
fill_up_shape (Wires, WiresFilled, 'area', 1, 100) //填充具有给定形状特征的区域中的孔。
opening_circle (WiresFilled, Balls, 9.5) //圆形开操作
connection (Balls, SingleBalls) //连通域
select_shape_std (SingleBalls, Rect, 'rectangle1', 90) //选择给定形状的区域。
difference (SingleBalls, Rect, IntermediateBalls) //两个图像的差异
gen_empty_region (Forbidden) //生成一个空区域
expand_gray (IntermediateBalls, Bond, Forbidden, RegionExpand, 4, 'image', 6) //填充区域之间的间隙(取决于灰度值或颜色)或拆分重叠区域。
opening_circle (RegionExpand, RoundBalls, 15.5) //开操作
sort_region (RoundBalls, FinalBalls, 'first_point', 'true', 'column') //排序
smallest_circle (FinalBalls, Row, Column, Radius) //最小圆
//显示结果
NumBalls := |Radius|
Diameter := 2 * Radius
meanDiameter := sum(Diameter) / NumBalls
mimDiameter := min(Diameter)
dev_display (RoundBalls)
if (I != NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
endif
stop ()
endfor
用到的几个算子:
min_max_gray–确定区域内的最小和最大灰度值。
shape_trans --用于变换区域的形状
fill_up_shape–填充具有给定形状特征的区域中的孔
select_shape_std–选择给定形状的区域
expand_gray–填充区域之间的间隙(取决于灰度值或颜色)或拆分重叠区域
参考资料:
[1]:http://blog.sina.com.cn/s/blog_d38f8be50102wbuk.html