HALCON示例程序ball电路板焊点识别、检测、测量程序剖析
示例程序源码(加注释)
介绍: ball.hdev: Inspection of Ball Bonding
*halcon窗口实时更新关闭
dev_update_window (‘off’)
*halcon关闭所有窗口
dev_close_window ()
*halcon打开新窗口
dev_open_window (0, 0, 728, 512, ‘black’, WindowID)
*读入图像
read_image (Bond, ‘die/die_03’)
*halcon显示读入图像
dev_display (Bond)
*halcon设置在“WindowID”界面中字体显示格式
*函数原型:set_display_font( : : WindowHandle, Size, Font, Bold, Slant : )
*函数原型:WindowHandle:设置的窗口ID;Size:字体大小;Font:字体(宋体、楷体。。。。。);Bold:是否加粗;Slant :是否使用斜体
set_display_font (WindowID, 14, ‘mono’, ‘true’, ‘false’)
*disp_continue_message 此函数会在屏幕右下角显示“单击”“运行”使程序继续运行。(其实就是加一个继续按钮)
*disp_continue_message(:: WindowHandle,Color,Box ?
*WindowID:显示的窗口;Color:显示颜色;Box :是否显示底色
disp_continue_message (WindowID, ‘black’, ‘true’)
*程序暂停运行,以便于查看
stop ()
*选中Bond图片中像素值于100-255的像素,生成一个区域Bright
threshold (Bond, Bright, 100, 255)
*求取刚刚提取出的区域的最小外接矩形,名称为Die
shape_trans (Bright, Die, ‘rectangle2’)
*设置显示的颜色(包括字体、区域、ROI等)
dev_set_color (‘green’)
*设置显示线宽
dev_set_line_width (3)
*设置显示区域的方式margin:边缘模式(显示区域只划出他的外边缘);Fill:填充模式(以填充方式显示区域)
dev_set_draw (‘margin’)
*显示刚刚求得的最小外接矩形
dev_display (Die)
disp_continue_message (WindowID, ‘black’, ‘true’)
stop ()
*剪裁图片,用区域Die去裁剪图片Bond,生成新的图片DieGrey
reduce_domain (Bond, Die, DieGrey)
*阈值选取
threshold (DieGrey, Wires, 0, 50)
*填充区域内的孔洞(不同于fillup)具有特征选择的功能,这里用到的使面积,不在最小最大设定范围的孔洞将不会被填充
*函数原型:fill_up_shape(Region:RegionFillUp:Feature,Min,Max:)
*Region:区域;RegionFillUp:填充后的区域;Min:最小填充孔洞;Max:最大填充孔洞
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(Region : RegionOpening : Radius : )
*Region :要进行开运算的区域;RegionOpening :开运算过后的区域;Radius :用于开运算元素的半径
*这里就是要去掉圆形焊点后边的小尾巴
opening_circle (WiresFilled, Balls, 15.5)
*又是相关的显示设置了
dev_set_color (‘green’)
dev_display (Balls)
disp_continue_message (WindowID, ‘black’, ‘true’)
stop ()
*分割连通域,我们做了上述的这么多事情,怎么才能把焊盘一个一个的找出来呢,虽然现在接近成功,但还不行,因为现在的区域还是一个,(就如CAD的图层与PS的图层差不多)就是虽然不相连但是还是认为是一坨,connection就是把这些不相连的给分成不同的区域。两个参数,第一个是传入区域(要分割的);第二个是分割后的。在halcon上最直观的显示就是由一个颜色变得五彩缤纷了
connection (Balls, SingleBalls)
*特征选择函数,选择特定的特征是我们做简单的图像分析常用的算子。可以通过区域的特征(面积、圆度、矩形度。。。。。)不同筛选出我们要的区域。
*这里用到的使圆度;圆度介于0.85-1.0的区域将会被选中
select_shape (SingleBalls, IntermediateBalls, ‘circularity’, ‘and’, 0.85, 1.0)
*sort_region - 根据区域的相对位置对区域进行排序
*函数原型:sort_region(Regions:SortedRegions:SortMode,Order,RowOrCol ?
*Regions:区域们;SortedRegions:对区域排序完成的区域;SortMode:排序模式;Order:顺序还是倒序;RowOrCol :行优先还是列优先
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 := sum(Diameter) / NumBalls
mimDiameter := min(Diameter)
dev_display (Bond)
disp_circle (WindowID, Row, Column, Radius)
dev_set_color (‘white’)
for i := 1 to NumBalls by 1
*这里大家仔细看一下就明白了
if (fmod(i,2) == 1)disp_message (WindowID, 'D: ' + Diameter[i - 1], 'image', Row[i - 1] - 2.7 * Radius[i - 1], max([Column[i - 1] - 60,0]), 'white','false')elsedisp_message (WindowID, 'D: ' + Diameter[i - 1], 'image', Row[i - 1] + 1.2 * Radius[i - 1], max([Column[i - 1] - 60,0]),'white','false')endifendfor
dump_window (WindowID, ‘tiff_rgb’, ‘./ball’)
dev_set_color (‘green’)
dev_update_window (‘on’)
disp_continue_message (WindowID, ‘black’, ‘true’)
stop ()
dev_close_window ()
处理思路
这个焊点检测拿到图片后我们想到的他的一个特点是圆的对吧,在一个我们看一下像素值很低,这个例程就是使用了这个特性完成了这个。先对电路板进行了一个选取,减少非电路板部分对检测的干扰。然后通过阈值选择出焊点,因为照片噪点或者产品本身就有噪点,对封闭区域做了一个填充。但是影响因素很多,这时使用圆形元素进行了一个开运算,搞掉那些影响。之后进行了特征筛选,用到了圆度这一特性进行筛选。轻易的就选出了圆形焊点区域,之后做了一个简单地排序与计算最后显示出结果,大功告成。
后记
大家有什么问题可以向我提问哈,我看到了第一时间回复,希望在学习的路上多多结交良师益友。