• 热门专题

在matlab中正确的使用水坝算法分割图像

作者:bfcat  发布日期:2013-12-11 19:59:48
Tag标签:matlab  分割图像  
  • 水坝算法,也就是watershed,是一种经典而又很好用的图像分割方法。最近在matlab的网站上看到一篇讲解这个算法的帖子,看看如何能够正确的使用这个算法。

    例如,这是一张图像,我们希望用watershed的方法对这幅图像进行分割。


     

    当然,在matlab里面,直接对这幅图像使用watershed这个函数,并不能得到很好的分割结果。这里我们看看如何能够正确的使用watershed分割这个图像,同时也看看watershed变换和watershed分割的区别。

     

    首先,我们直接调用watershed,看看结果是什么样的

     

    url = 'http://www.bfcat.com/wp-content/uploads/auto_save_image/2013/12/004306JQI.png';
    bw = imread(url);
    L = watershed(bw);
    Lrgb = label2rgb(L);
    imshow(Lrgb)

     


     

    刚刚看到结果的时候,我们可能很纳闷分割结果为什么是这个样子。让我们用imfuse这个函数,将两幅图像显示在一起,将图像中的一个区块放大看
     
    imshow(imfuse(bw,Lrgb))
    axis([10 175 15 155])

     

     

     
    我们可以看出,watershed变换总会在每一个局部最小的地方给出一个水坝区域。这些小的黑色“点”就是局部最小值,因此在每个周围都有一个watershed区域。
     
    即使我们填补了这些空洞,我们也没法获得用户想要的分割效果。这就是我们要注意到的watershed变换和watershed分割的区别。也就是说,watershed分割算法是watershed变换的一种应用,而简单的对图像进行watershed变换,并不能达到最终的分割目的。
     
    这里有一个帖子 The Watershed Transform: Strategies for Image Segmentation,详细介绍了watershed变换的原理。这个帖子的中心思想概括为一句话:用水坝变换进行图像分割的关键,在于先要将图像进行转换,使得目标对应不同的“蓄水池”. 
     
    对于这样一副图像,包含一些接近圆形,互相接触的区块,我们可以使用距离变换来生成另一幅图像,其中的目标对应“蓄水池”。
     
    进行距离变换之前,我们先清理一下噪声。bwareaopen这个“开”运算,可以用来清除很小的点。
     
    bw2 = ~bwareaopen(~bw, 10);
    imshow(bw2)
     

     
    然后我们进行距离变换。
     
    D = -bwdist(~bw);
    imshow(D,[])
     

     
    基于这个图像,我们再来做水坝变换
     
    Ld = watershed(D);
    imshow(label2rgb(Ld))
     

     
    这里的白线就是分割的边缘。由于原图是二值图,因此我们很容易区分前景和背景。
     
    bw2 = bw;
    bw2(Ld == 0) = 0;
    imshow(bw2)
     

     
    这样的结果中包含了不少过分割。原因和上面提到的一样,局部最小太多。对于这种情况,通用的技巧是,在基于watershed的图像分割中使用imextendedmin这个函数过滤掉一些特别小(指区域小)的局部最小。然后,我们修改距离变换的结果,让滤波后的区域不会出现局部最小值,这个操作叫做“强制最小(minima imposition)”,可以用imimposemin这个函数实现。
     
    使用imextendedmin将会只在我们希望分割的区块中间产生小点。然后我们使用imshowpair来将模板叠加到原图上。
     
    mask = imextendedmin(D,2);
    imshowpair(bw,mask,'blend')
     

     
    最后,我们我们修改距离变换的结果,让其只在想要的位置具有局部最小。然后进行watershed。这就是我们想要的结果了。
     
    D2 = imimposemin(D,mask);
    Ld2 = watershed(D2);
    bw3 = bw;
    bw3(Ld2 == 0) = 0;
    imshow(bw3)
     
     

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规