勇哥的实验:halcon阈值分割算子细谈(七)拓扑分割算子 watersheds系列算子(分水岭算子),梯度的分水岭,距离变换分水岭

阈值分割引言

C#
阈值分割有非常多的算法,大体上分为全局和局部算法。
全局算法包括全局固定阈值和基于图像直方图的阈值,局部算法包括局部动态阈值分割。
基于图像直方图阈值分割的方法也有很多,比如常规的高斯滤波双峰法,OTSU大津法。
但是这类所有的法都基于一个假设:图像是有前景和背景的,待分割目标处于背景中,即图像直方图是双峰的。
如果因为非均匀光照导致待分割目标不处于背景或前景中,即图像直方图无双峰,
那么基于图像直方图的所有法都是不甚理想的
只能在此基础上进行一定的变换,例如nbl算法等,这些都属于局部算法。

任何算法,都会基于假设空间的。没有假设空间,所有算法性能一致。包括经典算法和深度学习算法。

本系列的贴子勇哥通过实验来细品它们之间的差别,以求以后可以精准应用。


这一节谈谈拓扑分割算子。

比如:Watersheds系列算子,分水岭系列。

watersheds(Image : BasinsWatersheds : : )

watersheds_threshold(Image : Basins : Threshold : )

功能:通过阈值实现图像的分水岭算法分割

watersheds_marker(Image, Markers : Basins : : )(halcon12不支持)


分水岭的原理

分水岭算法基本思想:

一个灰度影像可以看做一个高程影像,灰度的变化就是地形的起伏。假设向该区域不断注水,则地势较低的位置会首先被淹没,随着水位的升高淹没的区域也会不断提高,而初始位置称为集水盆。而分水岭算法就是基于此基本思想,首先假设图像灰度值为高度值,通过集水盆区域不断注水使得每个淹没区域不断扩大,而当水淹没到一定高度时两个集水盆会相连合并为同一个区域,此时就应该在这两个集水盆之间建立拦水坝以阻止区域的合并,持续次过程直到注水高度满足要求得到所有集水盆的淹没区域。

分水岭算法主要用于图像的分割,如果目标物体是连接在一起的,则分割起来会很困难。此时经常采用分水岭分割算法,会得到比较好的效果。分水岭分割算法把图像看成一幅地形图,亮度比较强的区域像素值较大,亮度暗的区域像素值比较小,通过寻找汇水盆地和分水岭界线对图像进行分割。分水岭的计算过程是一个迭代标注过程。分水岭比较经典的计算方法是L. Vincent提出的。在该算法中,分水岭计算分两个步骤,一个是排序过程,一个是淹没过程。首先对每个像素的灰度级进行从低到高排序,然后在从低到高实现淹没过程中,对每一个局部极小值在h阶高度的影响域采用先进先出(FIFO)结构进行判断及标注。


第1步:
通过分水岭算法watersheds()获取图像的盆地。

这里写图片描述

第2步:
根据第一步分水岭算法分离结果,若盆地部分的灰度**< threshold**,则被合并到一起。设B1和B2分别为相邻盆地的最小灰度值,W为将盆地分割为两个盆地的最小灰度值。则分割结果为:

这里写图片描述
这里写图片描述

案例一 

watersheds_threshold的基本用法

dev_set_draw ('margin')
dev_set_line_width (2)
dev_set_colored (12)
read_image (Meningg6, 'meningg6.png')
dev_close_window ()
get_image_size (Meningg6, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
gauss_filter (Meningg6, ImageGauss, 3)
dev_display (ImageGauss)

*这里只是看下watersheds算子的效果,在本例中没发挥作用
watersheds (ImageGauss, Basins1, Watersheds)
dev_display (ImageGauss)
dev_display (Basins1)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

watersheds_threshold (ImageGauss, Basins2, 10)

intensity(Basins2, ImageGauss, Mean, Deviation)
Mask := Mean [<=] 140
*这个算子是按Mask来批量选择对象,省略循环的利器
select_mask_obj(Basins2, SelectedObjects, Mask)
dev_display (ImageGauss)
dev_display (SelectedObjects)


代码中,我们修改140更大一些,可以选择到灰度更浅一些region
但是背景也就是在147左右,所以其实做灰度平均值intensity也不是完美的解决办法。
究其原因还是因为分水岭生成的region并不是紧紧包住缺陷的原因。

Mask := Mean [<=] 140


image.png


案例二

边缘振幅+分水岭阈值实现图像分割(也可以称为梯度的分水岭分割

dev_set_draw ('fill')
dev_set_line_width (2)
dev_set_colored (12)
read_image (ImageLogo, 'mvtec_logo.png')
dev_close_window ()
get_image_size (ImageLogo, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (ImageLogo)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
gauss_filter (ImageLogo, ImageGauss, 9)
sobel_amp (ImageGauss, EdgeAmplitude, 'sum_abs', 3)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
watersheds_threshold (EdgeAmplitude, Basins, 14)
dev_display (Basins)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
return ()


源图
边缘幅度图
结果图

例三

距离变换+watersheds_threshold等实现分割

dev_set_draw ('margin')
dev_set_colored (12)
read_image (Image, 'pellets')
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
threshold (Image, Region, 105, 255)
 * 计算连通域
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20, 99999)
dev_display (Image)
dev_display (SelectedRegions)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
 * 距离变换
distance_transform (SelectedRegions, DistanceImage, 'octagonal', 'true', 380, 350)
convert_image_type (DistanceImage, DistanceImageByte, 'byte')
invert_image (DistanceImageByte, DistanceImageInv)
 * 扩大图像灰度范围[0,255]
scale_image_max (DistanceImageInv, DistanceImageInvScaled)
watersheds_threshold (DistanceImageInv, Basins, 5)
dev_display (DistanceImageInvScaled)
dev_display (Basins)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
 * 
dev_display (Image)
dev_display (SelectedRegions)
dev_set_color ('blue')
dev_display (Basins)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
 * 图像求交
intersection (Basins, SelectedRegions, SegmentedPellets)
dev_display (Image)
dev_set_colored (12)
dev_display (SegmentedPellets)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
return ()

源图阈值化图距离变换图watersheds_threshold图结果图

--------------------- 

作者:hackpig

来源:www.skcircle.com

版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864