上篇我们讲到通过动态定位焊点的ROI区域,以排除压块位置跳舞的影响。
正常情况下,我们的region可以通过下移30个像素,取得很好的覆盖ROI,如图:
但是,上面的算法在移动30个像素时,无法处理下面这样的情况,如图:
因此,我们的算法必须能检测我们要移动的30个像素是否会超出焊片(白色)的区域。
我们先把程序放上来:
list_files ('C:/Users/Administrator/Desktop/焊点图片', ['files','follow_links'], ImageFiles) tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima)$','ignore_case'], ImageFiles) for Index := 0 to |ImageFiles| - 1 by 1 read_image (Image, ImageFiles[Index]) gen_rectangle1 (ROI_0, 114.5, 183.5, 397.5, 599.5) reduce_domain(Image, ROI_0, ImageReduced) threshold (ImageReduced, Regions, 123, 255) closing_rectangle1(Regions, RegionClosing2, 120, 320) fill_up(RegionClosing2, RegionFillUp1) connection(RegionFillUp1, ConnectedRegions1) select_shape(ConnectedRegions1, SelectedRegions1, 'area', 'and', 15000, 99999) smallest_rectangle2(SelectedRegions1, Row, Column, Phi, Length1, Length2) *计算移动30个像素的区域是否会超出焊片区域 *算法是通过采样一行的像素的灰度值的和是否超出一个阈值范围来判定是否要超出范围 x2:=Row+Length1+1 y2:=Column-Length2 len:=Length2*2 tuple_int(y2, Inty) tuple_int(len,Intlen) tuple_int(x2,Intx) for k:=0 to 30 by 1 yary:=[Inty:Inty+Intlen-1] tuple_gen_const(Intlen, Intx+k, intx1) get_grayval(Image,intx1 ,yary, Grayval) tuple_sum(Grayval, Sum) if(Sum<11000) break endif endfor Row:=Row+k gen_rectangle2(Rectangle1, Row, Column, Phi, Length1, Length2) reduce_domain(Image, Rectangle1, ImageReduced2) mean_image(ImageReduced2, ImageMean, 15, 15) var_threshold(ImageMean, Region, 15, 15, 0.2, 2, 'dark') connection(Region, ConnectedRegions) select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 150, 99999) closing_circle(SelectedRegions, RegionClosing1, 6.5) smallest_circle(RegionClosing1, Row2, Column2, Radius) gen_circle(Circle, Row2, Column2, Radius) dev_set_draw('margin') dev_set_line_width(2) dev_set_color('red') dev_display(Image) dilation_circle(Circle, RegionDilation, 3.5) dev_display(RegionDilation) stop() endfor
在上面的例程中,
get_grayval(Image,intx1 ,yary, Grayval)
这句代码实现取一行点的灰度值到数组Grayvalue。
后面的代码则检查这一行灰度值的和是否超出一个阈值范围,超出则表示检测到非白色焊片的区域,退出循环。
tuple_sum(Grayval, Sum) if(Sum<11000) break endif
我们来看几个本代例代码处理好的例子:
这些例子可以看到,动态焊点ROI的算法,很好的处理了各种可能的情况,效果非常好。
当然,本篇只是解决上篇算法的缺陷,焊点误选还是存在严重的问题。这个问题下篇我们会继续讨论。
通过本文完善后的动态确定焊点ROI的算法,我们很好的解决了焊点靠近压块边界时候的粘连问题。
例如下图最下面那两个焊点。
另外,本篇开始笔者把halcon由版本10升到了12.
halcon12有几个关于数组新的特性。
例如: yary:=[Inty:Inty+Intlen-1]
这段代码里,数组yary取一行像素灰度值,数组共计147个元素。
举个简单的常量批量定义的例子: t1:=[0,100] 它定义数组t1并且批量赋值,其值为0到100
上面是简化的写法,完整的语法如: t1=[0,1,100] 即起始1,结束100,步长为1。
这个特性有些像python里的元组。
而且在数组批量赋值时,不光可以指定常量,还可以指定变量及表达示,例如上面的代码: yary:=[Inty:Inty+Intlen-1]
在本例子里面,如果没有halcon12提供的这个批量赋值数组的新特性的话,你可以想像填充一个30行147列的数组的代码是多么笨拙,并且会让halcon的解释执行变得效率非常低下。
有关halcon数组的定义与使用可以参考下面的贴子:
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

