一,击中击不中变换原理
1.1 击中击不中利用的是形态学中的腐蚀。官方介绍是这样的,“击中击不中变换是形态学形状检测的基本工具,是用来查找像素局部模式的形态学运算符,其中局部是指结构元素的大小。 两个不相交集合B=(B1, B2),称B为复合结构元素。则击中击不中变换为:用B1去腐蚀x,然后用B2去腐蚀X的补集,得到的结果相减就是击中击不中变换。”官方的解释难以让人理解。还有一种简单的说法。击中-击不中运算常用于二值图像,它用于基于结构元素的配置,从图像中寻找具有某种像素排列特征的目标,如单个像素、颗粒中交叉或纵向的特征、直角边缘或其他用户自定义的特征等。计算时,只有当结构元素与其覆盖的图像区域完全相同时,中心像素的值才会被置为1,否则为0。
二、不过以上总结都不足以让人充分理解击中击不中,下面我用最朴实无华的文字解释,并附以Halcon代码详解。
*实例,利用击中击不中变换,提取铆钉,此效果可以自动剔除其余尺寸或者形状与铆钉不一致的工件区域。
*Halcon击中击不中变换,算子hit_or_miss(inputregion,structBoundary1,structBoundary2,outregion,row,col)
*结构元素structBoundary1,structBoundary2一定都是构建好的区域边界,而不是区域。
*击中击不中原理:构建两个结构元素,structBoundary1保证完全被包含在需要提取的区域内,也就是结构元素structBoundary1
*一定要小于需要被提取的区域。structBoundary2保证与需要被提取的区域没有交集,也就是结构元素structBoundary2一定要大于
*需要被提取的区域(由于structBoundary2是边界,所以只要structBoundary2大于需要被提取的区域,他们就一定没有交集)。
*可以利用两个结构元素的尺寸大小,对于被提取区域来说,刚好一个在内,一个在外。让这样的结构元素尺寸,只满足需要被提取的
*区域。别的区域都不满足,结构元素一个在内,一个在外。这样就可以完美提取出需要的区域精确位置来。
* Image Acquisition 01: Code generated by Image Acquisition 01
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
list_files ('E:/图片', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
mean_image (Image, ImageMean, 255, 255)
dyn_threshold (Image, ImageMean, RegionDynThresh, 30, 'dark')
fill_up_shape (RegionDynThresh, RegionFillUp, 'area', 1, 10000)
opening_circle (RegionFillUp, RegionOpening, 80)
*构建结构元素,注意两个结构元素的中心坐标需要完全一致,而且结构元素位置应该完全被包含在图像定义域内。
*构建结构元素1
gen_circle (Circle, 250, 250, 95)
boundary (Circle, RegionBorder, 'outer')
*构建结构元素2
gen_circle (Circle1, 250, 250, 115)
boundary (Circle1, RegionBorder1, 'outer')
*击中击不中变换,注意最后两个参数,Row,Col需要与结构元素的中心坐标保持一致。
hit_or_miss (RegionOpening, RegionBorder, RegionBorder1, RegionHitMiss, 250, 250)
connection (RegionHitMiss, ConnectedRegions)
area_center (RegionHitMiss, Area, Row, Column)
count_obj (ConnectedRegions, Number)
if (Area>0)
dev_display (Image)
dev_display (RegionHitMiss)
set_tposition (WindowHandle, 10, 10)
write_string (WindowHandle, '找到数量:'+Number)
else
dev_display (Image)
endif
stop()
endfor