1. 程式人生 > >分水嶺演算法 matlab的三種實現方法 .

分水嶺演算法 matlab的三種實現方法 .

本文轉自:

clear,clc%三種方法進行分水嶺分割

%讀入影象

filename='sar1.bmp';

f=imread(filename);

Info=imfinfo(filename);

if Info.BitDepth>8   

f=rgb2gray(f);

end

figure,

mesh(double(f));%顯示影象,類似集水盆地

%方法1:一般分水嶺分割,從結果可以看出存在過分割問題

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);

%方法2:使用梯度的兩次分水嶺分割,從結果可以看出還存在過分割問題(在方法1的基礎上改進)

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;

figuresubplot(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);

%方法3:使用梯度加掩模的三次分水嶺演算法(在方法2的基礎上改進)

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;          %從原圖對分水嶺進行觀察

figuresubplot(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);