图像分割 之 分水岭算法

       分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表 面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分
水岭。
       分水岭的计算过程是一个迭代标注过程。分水岭比较经典的计算方法是L.Vincent 提出的。在该算法中,分水岭计算分两个步骤,一个是排序过程,一个是淹没过程。首先对每个像素的灰度级进行从低到高排序,然后在从低到高实 现淹没过程中,对每一个局部极小值在h 阶高度的影响域采用先进先出(FIFO)结构进行判断及标注。
       分水岭变换得到的是输入图像的集水盆图像,集水盆之间的边界点,即为分水岭。显然,分水岭表示的是输入图像极大值点。因此,为得到图像的边缘信息,通常把梯度图像作为输入图像,即

     g(x,y)=grad(f(x,y))={[f(x,y)-f(x-1,y)]2[f(x,y)-f(x,y-1)]2}0.5
 式中,f(x,y)表示原始图像,grad{.}表示梯度运算。
        分水岭算法对微弱边缘具有良好的响应,图像中的噪声、物体表面细微的灰度变化,都会产生过度分割的现象。但同时应当看出,分水岭算法对微弱边缘具有良好的响应,是得到封闭连续边缘的保证的。另外,分水岭算法所得到的封闭的集水盆,为分析图像的区域特征提供了可能。

        为消除分水岭算法产生的过度分割,通常可以采用两种处理方法,一是利用先验知识去除无关边缘信息。二是修改梯度函数使得集水盆只响应想要探测的目标。 为降低分水岭算法产生的过度分割,通常要对梯度函数进行修改,一个简单的方法是对梯度图像进行阈值处理,以消除灰度的微小变化产生的过度分割。即
               g(x,y)=max(grad(f(x,y)),gθ)
         式中,gθ 表示阈值。
       分水岭分割技术是一种很优秀的且得到了广泛应用的分割技术,从本质上讲,它属于一种基于区域增长的分割方法,但它得到的确是目标的边界,且是连续、 闭合、但像素宽的边界。在很多领域,这种分割技术都得到了广泛的应用,但分水岭分割却有一个致命的弱点,那就是容易产生过分割,对于噪声和细密纹理非常敏 感,使其常常产生严重的过分割结果。所以,针对这个问题,很多人提出了很多种改进的分水岭分割技术。综合来讲,大概也就三类。其一,分割预处理。既在应用 分水岭分割之前对图像进行一些预处理,诸如除噪,求梯度图像,形态学重建,标记前景背景等等,一个目的,减少小的积水盆,从而减少过分割区域的数量。其 二,分割后处理。既在应用分水岭分割之后对结果图像进行合并处理。如果初始分割产生过多小区域,合并处理会具有很大的运算量,所以后处理的时间复杂度经常 较高,还有合并准则的确定,也是一件比较麻烦的事情,通常有基于相邻区域的平均灰度信息和边界强度信息的合并准则,不同的合并准则会得到不同的分割结果。 其三,就是既有预处理又有后处理的分割技术了,根据具体应用领域的要求,如果只是采取预处理或后处理还不能得到满意的效果,那就把他们都用上试试了。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像分割是指将图像分成若干个互不重叠的连通区域的过程,其中每个区域内的像素具有相似的属性,如颜色、纹理等。而分水岭算法一种基于图论的图像分割方法,它将图像看成一个拓扑图,通过模拟水流从高处到低处的过程来分割图像。 下面是使用Matlab实现分水岭算法进行图像分割的步骤: 1. 读入需要分割图像并显示出来: ``` img = imread('example.jpg'); imshow(img); ``` 2. 对图像进行预处理,包括灰度化、平滑化等: ``` gray = rgb2gray(img); smooth = imgaussfilt(gray, 2); ``` 3. 对图像进行边缘检测,可以使用Sobel算子或Canny算子: ``` edge = edge(smooth, 'sobel'); ``` 4. 对边缘进行膨胀操作,使得边缘区域更加明显: ``` dilate = imdilate(edge, ones(3)); ``` 5. 对图像进行分水岭算法分割: ``` labels = watershed(dilate); ``` 6. 将分割结果可视化: ``` mask = labels == 0; segout = img; segout(mask) = 255; imshow(segout); ``` 完整代码如下: ``` img = imread('example.jpg'); imshow(img); gray = rgb2gray(img); smooth = imgaussfilt(gray, 2); edge = edge(smooth, 'sobel'); dilate = imdilate(edge, ones(3)); labels = watershed(dilate); mask = labels == 0; segout = img; segout(mask) = 255; imshow(segout); ``` 运行后即可得到分割结果。需要注意的是,分水岭算法不适用于所有类型的图像,对于一些复杂的图像可能需要更加复杂的算法来进行分割

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值