最近看到一个例子,来自一个论坛,提问者想要计算图中木头的数量,悬赏了分值但是没人回复,我看到的时候这帖子已经过去好几年了。作为一个肤浅的初学者,我觉得这问题很有趣,所以打算从这个例子入手,研究下Halcon中的图像处理。
首先,从二值化开始,这张图在刚开始二值化之后出现一些问题。阈值设的高了,会弱化边角一些木头的局部区域,设的低了,会造成一些粘连。而且图像中还有一些干扰。如何在保留边角局部信息的情况下尽可能的防止粘连,是个问题。
结合这个问题,我的思路是分两步走。先把边角一些小的木头区域提取出来,再专门解决粘连的问题,问题得到了解决。
提取较小区域
区分大小的依据主要是面积,在做了一些基本的预处理之后,可以把较小的一部分区域图像,如靠近四个边的部分木头,先分割出来了。这个过程中,需要对木头边缘做一些处理,去掉外圈的树皮,和一些干扰的区域,提取出木头截面的大块部分。
read_image (Image, 'G:/qing/Pic/wood.jpg')
get_image_size (Image, Width, Height)
rgb1_to_gray(Image,grayImage)
threshold (grayImage, Bright, 60, 255)
fill_up(Bright,fillRegion)
opening_circle (fillRegion, RegionOpening, 5.5)
select_shape (RegionOpening, SelectedRegions, 'area', 'and', 100, 200000)
intersection(SelectedRegions, Bright, RegionIntersection)
opening_rectangle1 (RegionIntersection, Cut, 1, 7)
connection (Cut, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions2, 'area', 'and', 500, 10000)
count_obj(SelectedRegions2,number1)
得到下图:
分割较大区域
这一步就比较简单了,没有小面积区域的顾虑,可以做下腐蚀,让边缘更加清晰。这样就分割开来了。
select_shape (ConnectedRegions1, BigRegions2, 'area', 'and', 10000, 1000000)
erosion_circle(BigRegions2,erisionRegion1,3.5)
connection (erisionRegion1, ConnectedRegions2)
select_shape (ConnectedRegions2, SelectedRegions3, 'area', 'and', 150, 200000)
区域合并与计数
把上一部分割出的大小区域分别合并,即得到木头的总数了。
count_obj(ObjectsConcat,number3)
dev_display(ObjectsConcat)
set_display_font (WindowHandle,18, 'mono', 'true', 'true')
disp_message(WindowHandle, 'Number of logs : '+number3, 'image', 30, 50, 'blue', 'true')
btw:这个例子我也做过分水岭算法的测试,但是效果不尽如人意,主要是分割出来的区域太多了,比如图中那片白色的干扰物、右小方的竹棍等,也分割出来了。而边角一些木头的边缘区域又很难顾及到。也可能是参数设置的不够好,所以这个算法我还在研究。
以上是我自己的一些浅薄的思路,希望随着学习的深入,能发现更好的方式。