halcon例程解析:球焊检验——ball. hdev
1. 效果展示
在下图中检测圆形焊接
原图

结果

2. 思路分析
本方案的目的是在电路板上检测圆形的球焊,观察整个电路板,球焊位置的特点,思路有:
- 灰度值
- 面积
- 圆度
此例程思路如下:
- 分割出电路板的区域:利用电路板区域与背景区域的灰度值区别,电路板区域为矩形
- 检测电路板中疑似焊接区域的部分:依靠灰度值,灰度值较低
- 优化感兴趣区域:按面积填充、开运算消除干扰区域、平滑边界(开运算尺度相对要大)
- 按圆度检测球焊区域,此时基本检测完成
- 排序、显示等
2.1 分割电路板区域
threshold (Bond, Bright, 100, 255)
shape_trans (Bright, Die, 'rectangle2')
电路板大部分区域都比背景亮,阈值分割选择大于100的部分,再找到区域的外接矩形
2.2 检测电路板中疑似焊接区域的部分
reduce_domain (Bond, Die, DieGrey)
threshold (DieGrey, Wires, 0, 50)

2.3 优化感兴趣区域
fill_up_shape (Wires, WiresFilled, 'area', 1, 100)
按面积填充区域

opening_circle (WiresFilled, Balls, 15.5)
开运算处理,去除小区域、平滑边缘

connection (Balls, SingleBalls)
select_shape (SingleBalls, IntermediateBalls, 'circularity', 'and', 0.85, 1.0)
依靠圆度检测,基本检测完成

完整代码
* ball.hdev: Inspection of Ball Bonding
*
dev_update_window ('off')
dev_close_window ()
dev_open_window (0, 0, 728, 512, 'black', WindowID)
read_image (Bond, 'die/die_03')
dev_display (Bond)
set_display_font (WindowID, 14, 'mono', 'true', 'false')
disp_continue_message (WindowID, 'black', 'true')
stop ()
threshold (Bond, Bright, 100, 255)
shape_trans (Bright, Die, 'rectangle2')
dev_set_color ('green')
dev_set_line_width (3)
dev_set_draw ('margin')
dev_display (Die)
disp_continue_message (WindowID, 'black', 'true')
stop ()
reduce_domain (Bond, Die, DieGrey)
threshold (DieGrey, Wires, 0, 50)
fill_up_shape (Wires, WiresFilled, 'area', 1, 100)
dev_display (Bond)
dev_set_draw ('fill')
dev_set_color ('red')
dev_display (WiresFilled)
disp_continue_message (WindowID, 'black', 'true')
stop ()
opening_circle (WiresFilled, Balls, 15.5)
dev_set_color ('green')
dev_display (Balls)
disp_continue_message (WindowID, 'black', 'true')
stop ()
connection (Balls, SingleBalls)
select_shape (SingleBalls, IntermediateBalls, 'circularity', 'and', 0.85, 1.0)
sort_region (IntermediateBalls, FinalBalls, 'first_point', 'true', 'column')
dev_display (Bond)
dev_set_colored (12)
dev_display (FinalBalls)
disp_continue_message (WindowID, 'black', 'true')
stop ()
smallest_circle (FinalBalls, Row, Column, Radius)
NumBalls := |Radius|
Diameter := 2 * Radius
meanDiameter := mean(Diameter)
minDiameter := min(Diameter)
dev_display (Bond)
disp_circle (WindowID, Row, Column, Radius)
dev_set_color ('white')
disp_message (WindowID, 'D: ' + Diameter$'.4', 'image', Row - 2 * Radius, Column, 'white', 'false')
dev_update_window ('on')