勇哥大致看了一下halcon中有关region相关的官方例程,还是有一些很趣的东西。
因此有个想法是把它全部滤一遍,在这里记录一下以备查。
车道标志的快速检测
球头连接检查
球头连接检查2
填充区域之间的间隙(取决于灰度值)
填充区域之间的间隙(取决于灰度值)expand_gray_ref
填充区域之间的间隙或分割重叠区域
(1)车道标志的快速检测
autobahn.hdev
这是一个巧妙的图像分割的例子。
使用网格、找边缘、膨胀算子的组合,缩小了分割图像的范围。
非常值得借鉴。
效果如下:
首先,生成网格,再剪切。
目的是产生检测区域。
gen_grid_region (Grid, MinSize, MinSize, 'lines', 512, 512) clip_region (Grid, StreetGrid, 130, 10, 450, 502)
然后用下面的算子提取了感兴趣区域的轮廓。
reduce_domain (ActualImage, StreetGrid, Mask) sobel_amp (Mask, Gradient, 'sum_abs', 3) threshold (Gradient, Points, 20, 255)
最后膨胀一下区域,再reduce_domain,相当于形成了一个缩小范围的区域。
dilation_rectangle1 (Points, RegionDilation, MinSize, MinSize) reduce_domain (ActualImage, RegionDilation, StripGray) threshold (StripGray, Strip, 190, 255) fill_up (Strip, RegionFillUp)
* autobahn.hdev: 车道标志的快速检测 * dev_update_window ('off') dev_close_window () dev_open_window (0, 0, 768, 575, 'black', WindowID) MinSize := 30 get_system ('init_new_image', Information) set_system ('init_new_image', 'false') gen_grid_region (Grid, MinSize, MinSize, 'lines', 512, 512) clip_region (Grid, StreetGrid, 130, 10, 450, 502) dev_set_line_width (3) dev_set_color ('green') read_image (ActualImage, 'autobahn/scene_00') dev_display (ActualImage) stop () dev_display (StreetGrid) stop () for i := 0 to 28 by 1 read_image (ActualImage, 'autobahn/scene_' + (i$'02')) reduce_domain (ActualImage, StreetGrid, Mask) sobel_amp (Mask, Gradient, 'sum_abs', 3) threshold (Gradient, Points, 20, 255) dilation_rectangle1 (Points, RegionDilation, MinSize, MinSize) reduce_domain (ActualImage, RegionDilation, StripGray) threshold (StripGray, Strip, 190, 255) fill_up (Strip, RegionFillUp) dev_display (ActualImage) dev_display (RegionFillUp) endfor dev_set_line_width (1) dev_update_window ('on') set_system ('init_new_image', Information)
算子gen_grid_region 原来可以这样用,让人印象深刻呀!
(2)球头连接检查
ball.hdev
这个例子没什么亮点比较简单,但是有几个算子要记录一下:
fill_up_shape 关于它与fill_up的区别勇哥在下面已经说明了。
sort_region 排序region
最终目的取球头,并计算直径。
第一步:
*做矩形的粗略分割 threshold (Bond, Bright, 100, 255) shape_trans (Bright, Die, 'rectangle2')
第二步:
*fill_up_shape 相比fill_up多了一个参数“特性”,可以取下面的值 * 'anisometry', 'area', 'compactness', 'convexity', 'inner_circle', * 'outer_circle', 'phi', 'ra', 'rb' reduce_domain (Bond, Die, DieGrey) threshold (DieGrey, Wires, 0, 50) fill_up_shape (Wires, WiresFilled, 'area', 1, 100)
最后取圆,并排序:
opening_circle (WiresFilled, Balls, 15.5) …… select_shape (SingleBalls, IntermediateBalls, 'circularity', 'and', 0.85, 1.0) sort_region (IntermediateBalls, FinalBalls, 'first_point', 'true', 'column')
(3)球头连接检查2
ball_seq.hdev
这个例子也是检查球头,但这个例子更有价值一些。
因为用到了几个非常不错的算子:
min_max_gray
select_shape_std
expand_gray
特别是这个expand_gray算子,丫的太有用了!
* ball_seq.hdev: Inspection of Ball Bonding * 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) 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 】:
这个算子的签名是:min_max_gray(Regions,Image::Percent:Min,Max,Range)
此算子用于提取 Regions 所在区域图像的最大与最小灰度值。
其工作过程是:计算像素的数量百分比对应于输入图像的区域。然后,它在直方图的两边向内移动此像素数,并确定最小和最大灰度值。
这里最重要的是参数的Percent的理解。
先统计区域内图像的灰度直方图,即在0-255灰度值范围内图像像素个数的分布频率图。 区域面积乘以Percent得到一个数,设为a,然后用a分别从0灰度值和255灰度值处向里截取a个像素点。 然后在剩下的像素点中取最小最大灰度值。 举个栗子: histo:=[4,1,1,1,…1,5,3,1],中间全是1, |histo|:=256 ,histo存放0-255灰度区间各灰度值的像素点个数 若a:=4 则 min:=1,max:=253,range:=252 (4是指直方图中灰度值为0的有4个像素,因此min:=1, max以此推导) percent的主要作用就是减少计算量,去除极小极大值的影响以尽量获得自己想要的灰度值的最小最大值。 以更好得到图像灰度特征。 如果percent为0,则不计算直方图以节省运行时间。
【select_shape_std】
这个算子签名是:select_shape_std(Regions : SelectedRegions : Shape, Percent : )
select_shape_std将给定区域的形状与默认形状进行比较。如果该区域具有相似的形状,则将其用于输出
Shape取值如下:
'max_area' 选择最大的区域。 “ rectangle1” 平行于坐标轴的周围矩形是通过运算符minimum_rectangle1确定的。如果面积差异百分比大于百分比,则采用该区域。 “ rectangle2” 任意方向的最小周围矩形是通过运算符minimum_rectangle2确定的。如果面积差异百分比大于百分比,则采用该区域。 注意,另一个更强大的算子select_shape,设置为“rectangularity”也可以达到效果。
【expand_gray】
expand_gray 填充区域之间的间隙(取决于灰度值或颜色)或拆分重叠区域
这个算子在本例中的效果是这样的:
1. difference之后的效果
2. expand_gray之后的效果
3. expand_gray+ opening_circle的效果
4. 仅显示opening_circle的效果
(1) (2)
(3) (4)
因此,在这个例子里面,expand_gray只是向外扩展的面积,让opening_circle效果更好些,
了是让后面的smallest_circle(最小圆)结果更准确。
下面会单独介绍这个算子。
(4)填充区域之间的间隙(取决于灰度值)
expand_gray.hdev
这个expand_gray算子签名如下:
expand_gray(Regions, Image, ForbiddenArea : RegionExpand : Iterations, Mode, Threshold : )
regions 是要操作的区域
Image 要操作的图片
forbiddenArea 是禁止区域,这个区域不参加计算
Iterations 迭代次数
Mode 取值image或者region,前者为填充region间隙,后者为拆分重叠的region
Threshold 阈值
expand_gray算子作用:填充区域之间的间隙(取决于灰度值或颜色)或拆分重叠区域。
当mode='image'时,作用是填充region之间原间隙, mode='region'时为拆分重叠区域。
expand_gray可以关闭输入区域之间的间隙,这是由于分割运算符中的小区域受到抑制(例如,模式“ image”), 或分离了重叠区域“ region”)。 两种用途均来自区域扩展。算子通过向一个区域添加一个像素宽的“条带”来实现, 该区域的灰度值或颜色与该区域边界上相邻像素的灰度值或颜色的差异最大为阈值(在每个通道中)。 对于“cyclic”类型的图像(例如,方向图像),还将灰度值差至少为255减去阈值的点添加到输出区域。 扩展仅在指定为非“禁止”(参数ForbiddenArea)的区域中进行。 迭代次数由参数Iterations确定。通过传递“ maximal”,expand_gray进行迭代直到收敛,即直到不再发生更改为止。 通过为该参数传递0,将返回所有非重叠区域。两种操作模式(“image”和“region”)在以下方面有所不同: 'image' 输入区域会反复扩展,直到它们接触另一个区域或图像边界,或者由于灰度值差异过大而停止扩展。 因为 expand_gray同时处理所有区域,所以区域之间的间隙均匀地分布到具有相似灰度值的所有区域。 通过将重叠区域均匀地分布到两个区域,可以将重叠区域分割。 'region' 不执行输入区域的扩展。相反,通过将重叠区域均匀地分布到具有匹配的灰度值或颜色的区域,仅分割重叠区域。 注意 因为区域仅扩展到具有匹配的灰度值或颜色的区域,所以通常在输出区域之间将保留间隙,即,分割不完整。
示例程序说明:
这个示例程序仅演示了填充Region间的间隙的功能,即mode='image'时的情况。
关于mode='region'的情况,请参见后介绍的 (6)填充区域之间的间隙或分割重叠区域 的例子说明。
expand_gray算子和expand_region算子相似,区别仅仅是前者填充区域之间的间隙时取决于灰度值或颜色。
首先用regiongrowing图片分割,效果如下:
expand_gray的效果。
expand_gray (Regions, Image, EmptyRegion, RegionExpand, 'maximal', 'image', 4)
从下图的效果来看,这个所谓的填充region之间的间隙效果就如同大的region内的小region被吃掉了,画面上变干净了。
经过测试,参数threshold取值越小,得到的region细节越多,如果取值越大,则大量的region将会合并。
例子源码:
read_image (Image, 'fabrik') dev_set_colored (6) regiongrowing (Image, Regions, 1, 1, 1, 100) gen_empty_region (EmptyRegion) expand_gray (Regions, Image, EmptyRegion, RegionExpand, 'maximal', 'image', 4)
(5)填充区域之间的间隙(取决于灰度值)expand_gray_ref
expand_gray_ref.hdev
expand_gray_ref算子签名:
expand_gray_ref(Regions, Image, ForbiddenArea : RegionExpand : Iterations, Mode, RefGray, Threshold : )
相对于expand_gray来讲就是多了一个参数RefGray,即参考灰度。
下图是执行expand_gray的效果。
expand_gray (Regions, Image, EmptyRegion, RegionExpand, 'maximal', 'image', 4)
下图是本例源码执行expand_gray_ref的效果。
expand_gray_ref (Regions, Image, EmptyRegion, RegionExpand, 'maximal', 'image', Mean, 11)
示例源码:
read_image (Image, 'fabrik') dev_set_colored (6) regiongrowing (Image, Regions, 1, 1, 1, 100) gen_empty_region (EmptyRegion) intensity (Regions, Image, Mean, Deviation) expand_gray_ref (Regions, Image, EmptyRegion, RegionExpand, 'maximal', 'image', Mean, 4)
(6)填充区域之间的间隙或分割重叠区域
expand_region.hdev
expand_region算子的签名是:
expand_region(Regions, ForbiddenArea : RegionExpanded : Iterations, Mode : )
作用有两个:
(1) 填充region之间的间隙
(2) 拆分重叠的两个Region
regions 是要操作的区域
forbiddenArea 是禁止区域,这个区域不参加计算
Iterations 迭代次数
Mode 取值image或者region,前者为填充region间隙,后者为拆分重叠的region
示例程序刚好用到了上面两个作用,说明如下:
首先用regiongrowing算子进行图片分割,效果如下:
regiongrowing (Image, Regions, 1, 1, 3, 1000)
第一次expand_region的效果
expand_region (Regions, NoPixel, RegionExpanded1, 'maximal', 'image')
注意这次的Mode参数是image。这个时候是填充region间的间隙
从下图效果上来看,较大region里面的一些小region都被填充了,这也是迭代次数取值最大(maximal)造成的。
第二次expand_region的效果
首先是膨胀了region
dilation_circle (Regions, RegionDilation, 13.5)
特意设置了一个比较大的值13.5,为的是让几个region间产生了重叠部分。如下图:
然后再执行一次expand_region,注意这次的Mode参数是“region”
expand_region (RegionDilation, NoPixel, RegionExpanded2, 'maximal', 'region')
然后达到下图所示的Region重叠部分进行了拆分的效果。
例子源码:
read_image (Image, 'fabrik') regiongrowing (Image, Regions, 1, 1, 3, 1000) gen_empty_region (NoPixel) expand_region (Regions, NoPixel, RegionExpanded1, 'maximal', 'image') dev_display (Image) dev_set_draw ('margin') dev_set_colored (6) dev_display (RegionExpanded1) stop () dev_clear_window () dilation_circle (Regions, RegionDilation, 13.5) stop () expand_region (RegionDilation, NoPixel, RegionExpanded2, 'maximal', 'region') dev_display (Image) dev_display (RegionExpanded2)
---------------------
作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!

