视觉或图像信息,它是人类最有效的信息获取和交流方式,图像也因为其所含的信息量大、表现直观而在应用的多媒体中占据了重要的地位。 图像分割就是将图像表示为物理上有意义的连通区域的集合,是进行图像分析的第一步工作,也是解决起来比较困难的一个问题。对于如特征提取、目标识别等基于图像分割结果的接下来的任务的质量的好坏取决定性作用,因此有效合理的图像分割方法具有重要意义。 自20世纪70年代起,对图像分割的研究一直是焦点和热点,迄今为止已经有上千种分割方法,但是尚无通用的分割理论, 近年来, 随着各学科许多新理论和新方法的提出, 人们也提出了许多与一些特定理论、方法和工具相结合的分割技术。 目前只是较常用的基于形态学的分水岭分割、快速聚类分割、颗粒分割、区域阈值法和边缘检测法等。本文着眼最近流行的形态学分割方法,深入分析分水岭图像分割,并对其容易产生过分割的缺点进行了修改,最后提出了一种最佳的解决方案。 ## 基于形态学的分水岭分割 ### 分水岭分割的基本思想和常用方法 在图像处理中引入分水岭概念时,可以有两种形式: 1. 是将灰度图像看成是假想的地形表面; 2. 二是将待分割图像的梯度图像看成假想的地形表面。 ::: hljs-left ::: 在这两种形式中都将图像中每个像素的像素值表示该点的海拔高度。假设待分割的图像由目标和背景组成,这样,图像中目标的内部区域对应图中灰度较低的位置,而背景则对应图中的灰度值较高的位置,图中的灰度极小值点分布在目标内部。水面从这些极小值点处开始上涨,当不同流域中的水面不断升高到将要汇合在一起时(目标边界处),便筑起一道堤坝,最后得到由这些水坝组成的分水岭线,图像也就完成了分割。然而,用分水岭算法对灰度图像进行分割时,图中每个独立的局部底谷都划归为不同区域,最终导致“过分割”,即产生大量虚假的轮廓以致无法确认哪些是真正的轮廓。 常见的几种分水岭计算方法有:Beucher和Lanturjoul提出的基于浸没模型的分水岭算法,Friedlander在提出的有序算法[4],Beucher提出的基于有向箭头的有序算法。传统的分水岭算法存在一些缺点。第一,在处理的过程中,它们都连续多次对图像进行完整的扫描。这就意味着在每一步过程中,所有的像素都必须被扫描一次,这是非常费时的。第二,这些算法都没有一个固定的迭代次数,每一次迭代都必须对图像进行完整的扫描,而迭代的次数可能很大。所以,在目前的计算机中,这些算法的效率是非常低的. 模拟淹没算法的数学模型如下:假设表示二维灰度图像函数,其中为图像中像素点,表示的值域,是中的最小值,是中的最大值,有: 定义1:为门限函数,定义式如下: ![image.png](https://s2.51cto.com/images/20210609/1623210950989498.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 定义2:设为盆地(catchmentba sin) , M为盆地中的灰度最小值,定义式如下: ![image.png](https://s2.51cto.com/images/20210609/1623210959947041.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 定义3:测地距离(geodesicin fluencez one),设A为简单连通的区域,A内两点x, y间的路径P完全包含在A内,则x, y间的测地距离定义为: ![image.png](https://s2.51cto.com/images/20210609/1623210968520145.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 定义4:测地影响区域(geodesic influence zone)表示为,其中![image.png](https://s2.51cto.com/images/20210609/1623211039644053.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 是包含在A中的连通区域,则为A中的到测地距离小于所有像素的集合,定义式为: ![image.png](https://s2.51cto.com/images/20210609/1623210979995809.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 测地影响区域如图4-2所示,从图中可看出,A中不属于任何测地影响区域的像素组成了影响区域的轮廓(skeleton by influence zones),该轮廓即为![image.png](https://s2.51cto.com/images/20210609/1623211097662211.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 定义式为: ::: hljs-center ![image.png](https://s2.51cto.com/images/20210609/1623211112969152.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](https://s2.51cto.com/images/20210609/1623225372414951.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ::: hljs-center ![image.png](https://s2.51cto.com/images/20210609/1623225387466185.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ::: ::: 分水岭法常常因为噪音或细微的图像纹理的影响造成过度分割,所以在做分水岭法之前会先做消除噪音及纹理的前期处理程序,且在做完分水岭法之后会对过度分割的区域进行区域合并,由此可得到理想的分割效果。 ## 梯度优化的分水岭分割 ### 梯度优化 分水岭变换得到的是输入图像的集水盆图像,集水盆之间的边界点即为分水岭。其表示输入图像极大值点。 梯度优化方法为了得到图像边缘信息,把梯度图像作为输入图像。用形态学开闭运算结果作为梯度图像再进行阈值优化处理。这样图像既消除了非规则的细节扰动和明暗噪声,也进一步消除产生过分割的因素,再经分水岭分割时分割的区域数也相应地减少了,使得更有效地检测目标。 ### 梯度图像上的分水岭分割算法 实践证明,分水岭算法与图像的梯度有更大的联系, 而非图像本身。在梯度图像上进行分水岭算法分割,比在原始图像上分割得到的结果更加准确,所以梯度图像更适合作为分水岭算法的分割图像。因此把梯度图像作为输入图像,即: ![image.png](https://s2.51cto.com/images/20210609/1623225469463901.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 对梯度函数进行修改可以降低分水岭算法产生的过度分割。可以采用阈值处理,以消除灰度的微小变化产生的过度分割,即: ![image.png](https://s2.51cto.com/images/20210609/1623225488724850.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 首先用中偏低的灰度阈值对梯度图进行二值化,从而检测出物体和背景。物体与背景被处于阈值之上的边界点分开。随着阈值逐渐提高,就引起物体和背景的同时增长。当它们接触上而又不至于合并时,可用接触点来定义边界。用阈值限制梯度图像以达到消除灰度值的微小变化产生的过度分割,获得适量的区域。 以下例图可直观的看出用梯度图像比用简单的二值化图像做分水岭算法的输入图像出现的过分割现象有明显的减少。 ![image.png](https://s2.51cto.com/images/20210609/1623225570977503.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ```clear all; f=imread('C:\Users\lenovo\Desktop\timg.jfif'); Info=imfinfo('C:\Users\lenovo\Desktop\timg.jfif'); if Info.BitDepth>8 f=rgb2gray(f); end figure,mesh(double(f)); b=im2bw(f,graythresh(f));%二值化,注意应保证集水盆地的值较低(为0),否则就要对b取反 d=bwdist(b); %求零值到最近非零值的距离,即集水盆地到分水岭的距离 l=watershed(-d); %matlab自带分水岭算法,l中的零值即为风水岭 w=l==0; %取出边缘 g=b&~w; %用w作为mask从二值图像中取值 figure subplot(2,3,1),imshow(f); title('原图') subplot(2,3,2),imshow(b); title('图像二值化') subplot(2,3,3),imshow(d); title('集水盆地到分水岭的距离') subplot(2,3,4),imshow(l); title('分水岭图像分割') subplot(2,3,5),imshow(w); title('图像边缘提取') subplot(2,3,6),imshow(g); title('二值化图像取值') h=fspecial('sobel');%获得纵方向的sobel算子 fd=double(f); g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2); %使用sobel算子进行梯度运算 l=watershed(g); %分水岭运算 wr=l==0; g2=imclose(imopen(g,ones(3,3)),ones(3,3)); %进行开闭运算对图像进行平滑 l2=watershed(g2); %再次进行分水岭运算 wr2=l2==0; f2=f; f2(wr2)=255; figure subplot(2,3,1),imshow(f); title('原图') subplot(2,3,2),imshow(g); title('sobel算子梯度运算') subplot(2,3,3),imshow(l); title('分水岭图像分割') subplot(2,3,4),imshow(g2); title('开闭运算平滑后图像') subplot(2,3,5),imshow(l2); title('二次分水岭运算') subplot(2,3,6),imshow(f2); title('从原图对分水岭进行观察') h=fspecial('sobel'); %获得纵方向的sobel算子 fd=double(f); g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2); %使用sobel算子进行梯度运算 l=watershed(g); %分水岭运算 wr=l==0; rm=imregionalmin(g); %计算图像的区域最小值定位,该函数仅仅是用来观察为何分水岭算法产生这么多集水盆地 im=imextendedmin(f,2); %上面仅是产生最小值点,而该函数则是得到最小值附近的区域,此处的附近是相差2的区域 fim=f; fim(im)=175; %将im在原图上标识出,用以观察 lim=watershed(bwdist(im));%再次分水岭计算 em=lim==0; g2=imimposemin(g,im|em); %在梯度图上标出im和em,im是集水盆地的中心,em是分水岭 l2=watershed(g2); %第三次分水岭计算 f2=f; f2(l2==0)=255; %从原图对分水岭进行观察 figure subplot(3,3,1),imshow(f); title('原图') subplot(3,3,2),imshow(g); title('sobel算子梯度运算') subplot(3,3,3),imshow(l); title('一次分水岭图像分割') subplot(3,3,4),imshow(im); title('提取最小值附近区域') subplot(3,3,5),imshow(fim); title('标识出最小值') subplot(3,3,6),imshow(lim); title('二次分水岭图像分割') subplot(3,3,7),imshow(g2); title('提取集水盆地中心与分水岭') subplot(3,3,8),imshow(l2); title('三次分水岭图像分割') subplot(3,3,9),imshow(f2); title('从原图对分水岭进行观察') ``` 随机选定一个海岸线卫星 ![image.png](https://s2.51cto.com/images/20210609/1623225639173009.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ```clear all; f=imread('chepai.jpg'); Info=imfinfo('chepai.jpg'); if Info.BitDepth>8 f=rgb2gray(f); end figure,mesh(double(f)); ``` ![image.png](https://s2.51cto.com/images/20210609/1623225701223452.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 观察图片类似集水盆地,与分水岭分割法定义描述相符,以更直观的视觉感受,为接下来图像分割做准备。 ```b=im2bw(f,graythresh(f));%二值化,注意应保证集水盆地的值较低(为0),否则就要对b取反 d=bwdist(b); %求零值到最近非零值的距离,即集水盆地到分水岭的距离 l=watershed(-d); %matlab自带分水岭算法,l中的零值即为风水岭 w=l==0; %取出边缘 g=b&~w; %用w作为mask从二值图像中取值 figure subplot(2,3,1),imshow(f); subplot(2,3,2),imshow(b); subplot(2,3,3),imshow(d); subplot(2,3,4),imshow(l); subplot(2,3,5),imshow(w); subplot(2,3,6),imshow(g); ``` ![image.png](https://s2.51cto.com/images/20210609/1623225744855035.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 易看出最终处理结果存在过分割问题,对图像质量产生较大影响,其将背景中一些细小的花纹也分割出来,即是上文中提到的分水岭算法本身对细节极其敏感的特性使然。 ## 使用梯度的两次分水岭分割 ```h=fspecial('sobel');%获得纵方向的sobel算子 fd=double(f); g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2); %使用sobel算子进行梯度运算 l=watershed(g); %分水岭运算 wr=l==0; g2=imclose(imopen(g,ones(3,3)),ones(3,3)); %进行开闭运算对图像进行平滑 l2=watershed(g2); %再次进行分水岭运算 wr2=l2==0; f2=f; f2(wr2)=255;figure subplot(2,3,1),imshow(f);subplot(2,3,2),imshow(g); subplot(2,3,3),imshow(l);subplot(2,3,4),imshow(g2); subplot(2,3,5),imshow(l2);subplot(2,3,6),imshow(f2); ``` ![image.png](https://s2.51cto.com/images/20210609/1623225792438205.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 结合分割效果良好的梯度优化方法,在这次改进方法中加入了梯度的优化。此外,本次改进还加入了sobel算子,使得图像分割之初就对图像进行一次简单的垂直方向滤波,简单有效地突出了图像的边缘。后将图像做取梯度运算,并将得出的梯度图像作为输入变量进行接下来的图像处理。第三步进行分水岭分割。通过数学形态学中的开闭运算对图像进行平滑去噪,可以看出图像经过开闭运算和梯度优化处理后,保留了重要的区域轮廓,消除了细节轮廓和噪声,明显比单纯只用分水岭算法时削弱了过分分割现象,这一点通过观察海岸线数字背景减少杂纹,以及海岸线明显更清晰的体现出了轮廓。 ## 使用梯度加掩模的三次分水岭算法 ```h=fspecial('sobel'); %获得纵方向的sobel算子 fd=double(f); g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2); %使用sobel算子进行梯度运算 l=watershed(g); %分水岭运算 wr=l==0; rm=imregionalmin(g); %计算图像的区域最小值定位,该函数仅仅是用来观察为何分水岭算法产生这么多集水盆地 im=imextendedmin(f,2); %上面仅是产生最小值点,而该函数则是得到最小值附近的区域,此处的附近是相差2的区域 fim=f; fim(im)=175; %将im在原图上标识出,用以观察 lim=watershed(bwdist(im));%再次分水岭计算 em=lim==0; g2=imimposemin(g,im|em); %在梯度图上标出im和em,im是集水盆地的中心,em是分水岭 l2=watershed(g2); %第三次分水岭计算 f2=f; f2(l2==0)=255; %从原图对分水岭进行观察 figure subplot(3,3,1),imshow(f); subplot(3,3,2),imshow(g); subplot(3,3,3),imshow(l); subplot(3,3,4),imshow(im); subplot(3,3,5),imshow(fim); subplot(3,3,6),imshow(lim); subplot(3,3,7),imshow(g2); subplot(3,3,8),imshow(l2) subplot(3,3,9),imshow(f2); ``` ![image.png](https://s2.51cto.com/images/20210609/1623225980661732.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 此次改进是在上一次的基础上进行,最大变化在于加入掩模的方法,通过每次分水岭计算,得出集水盆地的中心以及分水岭,并将此与分割后的图像进行叠加标示,共进行三次分水岭,两次掩模运算,能在最后一张海岸线处理中发现不同于图4-4的分割效果增进,在海岸线边缘部分的背景上用肉眼已经几乎察觉不到杂纹,即第三种方法分割效果是非常理想的,其将选定目标区域完整清晰的分割了出来。