对应示例程序:
segment_ball_bond_lead_frame.hdev
目标:对焊盘上的球键和引线进行检测
思路为:
1.读取图像,窗口初始化
2.先利用Blob分析的方法,对包含球键和引线的部分进行整体定位
3.利用fill_up将图像中的圆孔进行填充,再与没填充的前一步图像进行求差,得到球键的位置
4.通过closing_circle算子,进行适当填补,把引线区域与周围像素连在一起,然后再与整体定位图像进行求差,得到含有引线的嘈杂图像,再根据引线与球键相连的特性,计算嘈杂图像中每个区域 与 球键区域的重复面积比,设置参数,进行筛选,得到引线位置
5.为了检测没有球键的焊盘,该例程是这样实现的:正常情况下每幅图有两个焊盘,每个焊盘上都有对应的球键,那么求球键与焊盘的重复面积所占焊盘面积的比例λ,此时这个值是大于0的,因为焊盘包括球键所在的区域。但是如果某个焊盘上没有球键,比如上面的焊盘,那么这时上面的焊盘与下面的球键之间就不存在重复区域,则面积比λ就是0,即面积比等于0的焊盘就是没球键的,从而可以将这个没有球键的焊盘检测出来。算子select_shape_proto承担这个任务。
图像:
原图
整体定位图:
(Pic1)
定位球键 (Pic2)
(Pic3)
(Pic4 ) 由Pic2 和Pic3 得到
定位引线:
(Pic5)由Pic1 和Pic2 得到
然后根据重复面积比,筛选出直线和求骨架
测量结果显示:
代码:
//初始化
dev_update_off ()
dev_close_window ()
Path := 'bonds/ball_bond_lead_frame_'
read_image (Image, Path + '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', 'false')
*
NumImages := 8
for Index := 1 to NumImages by 1
read_image (Image, Path + Index$'02')
*
//焊盘的定位是基于Bolb分析实现的
* Find lead pins
//查找引线引脚 先整体定位含有球键和引线的区域
var_threshold (Image, Region, 300, 300, 0.6, 2, 'light') //用局部均值和标准差 阈值分割图像
closing_circle (Region, RegionClosing, 5) //闭操作 消弥狭窄的间断和长细的鸿沟,消除小的空洞,并填补轮廓线中的断裂。
connection (RegionClosing, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, ['height','width'], 'and', [250,300], [500,800])
select_gray (SelectedRegions, Image, SelectedRegionsGray, 'mean', 'and', 100, 255) //基于灰度特征的区域选择
fill_up (SelectedRegionsGray, RegionFillUp) //填充区域中的孔洞
*
*
* Determine ball bonds
//定位球键
closing_circle (RegionFillUp, RegionClosing1, 35) //闭操作
fill_up (RegionClosing1, RegionFillUp1) //填充孔洞
difference (RegionFillUp1, RegionClosing1, BallBonds) //求差异
dilation_circle (BallBonds, RegionDilation1, 8) //圆形膨胀
union1 (RegionDilation1, RegionUnion) //合并区域 得到焊盘球键
*
* Determine wire
//定位导线
difference (RegionClosing1, RegionFillUp, RegionDifference1) //求差异
connection (RegionDifference1, ConnectedRegions1) //连通域分割
select_shape_proto (ConnectedRegions1, RegionUnion, SelectedRegions1, 'overlaps_rel', 1, 13) //选择彼此有一定关系的区域
//上述算子是将筛选出的区域 逐个 与之前得到的焊盘区域 进行重叠
//如果重叠的面积所占的面积比在指定范围内 就筛选出来
//因为引线与焊盘是相连的 因此可以筛选出来
opening_rectangle1 (SelectedRegions1, RegionOpening1, 57, 7) //开操作
skeleton (RegionOpening1, Wire) //骨骼
*
* Evaluate and display results
*显示测量结果
shape_trans (RegionFillUp1, LeadPin, 'rectangle1') //矩形凸包 用来显示包含主要图像的大矩形
dev_display (Image)
dev_set_line_width (3)
dev_set_color ('white')
dev_display (LeadPin)
dev_set_color ('green')
dev_display (BallBonds)
dev_set_color ('yellow')
dev_display (Wire)
select_shape_proto (LeadPin, BallBonds, SelectedRegions2, 'overlaps_rel', 0, 1) //选择彼此有一定关系的区域
//这个实验中正常情况得到的是两个球键,如果某个焊盘上没有球键,那么BallBonds元组里面,就是只有一个球键(两个都没有,则BallBons就是空集)
//因为select_shape_proto算子是将每个待测区域都与 目标区域进行计算,
//而没有球键的焊盘 与 测量出的球键(在另一个焊盘上) 之间 没有交集
//也就意味着重复区域的面积为0,因此将与球键重复面积为0的区域 筛选出来 就是没有球键的焊盘
*计算了图案与区域内每个区域的交集面积。相对重叠是区域中各区域的相交面积与面积之比(以百分比表示)。
area_center (SelectedRegions2, Area, Row, Column) //计算区域的中心 和面积
if (|Area| > 0)
dev_set_color ('red')
dev_display (SelectedRegions2)
for J := 0 to |Area| - 1 by 1
disp_message (WindowHandle, 'No Bond', 'image', Row[J] - 30, Column[J] - 100, 'red', 'true')
endfor
endif
//显示提示信息
dev_display_caption (WindowHandle)
*
if (Index != NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
set_system ('store_empty_region', StoreEmptyRegion)
用到的几个算子:
difference–求两幅图像的差异
fill_up --填补图像中的孔洞
select_shape_proto --选择彼此有一定关系的区域
参考资料:
[1].https://www.cnblogs.com/xh6300/p/6648435.html