控制標記符分水嶺分割算法 此博文包含圖片

控制標記符分水嶺分割算法

 (2011-01-10 04:44:39)
標籤: 

控制標記符

 

分水嶺

 

//示例流程

①原圖像及默認的分水嶺變換:

>> f=imread('rice_tophat.png');
>> h=fspecial('sobel')
h =
     1     2     1
     0     0     0
    -1    -2    -1
>> fd=double(f);
>> g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2);%梯度,具體參《梯度》博文
>> L=watershed(g);
>> wr=L==0;%分水嶺脊線
>> subplot(121),imshow(f),subplot(122),imshow(wr)

控制標記符分水嶺分割算法
從圖中看到,過分割現象特別嚴重。這樣的結果完全沒有意義。
②計算圖像中大量局部最小區域的位置:

>> rm=imregionalmin(f);whos rm
  Name        Size             Bytes  Class      Attributes

  rm        253x251            63503  logical 

>> figure,imshow(rm)

控制標記符分水嶺分割算法
其中,白點標記的小區域均爲“局部最小區域”——這塊區域的亮度值相同且其周圍的亮度值都比它大。

③計算圖像的“擴展的最小變換”,即通過一個閾值來擴展“局部最小區域”(讓更多的與最小區域相似的像素合併到最小區域裏邊來):

>> im2=imextendedmin(f,45);%試了多次,閾值爲45左右效果較好

>> figure,imshow(im2)
>>fim=f;fim(im2)=175;figure,imshow(fim)%以灰色來顯示這些“局部最小區域”

控制標記符分水嶺分割算法

(此時,所有亮的區域均爲擴展的“局部最小區域”)
控制標記符分水嶺分割算法 
可以看到,將擴展的局部最小區域疊加到原圖像上後的效果。灰度區域灰度值爲175.

這個“擴展的局部最小區域”作爲內部標記符集合。

//不對,內部標記應選在要提取的目標上,這幅圖像中要提取的是米粒圖像,故作如下修改:

>>im2=~im2;%im2是 二值矩陣,取反即可

>>fim=f;fim(im2)=175;figure,imshow(fim,[])

控制標記符分水嶺分割算法
可見,已將米粒區域修改爲對應的“擴展最小區域”——這個作爲內部標記符
④尋找外部標記符:

>> temp=bwdist(im2);%距離變換

>>figure,imshow(temp,[])

控制標記符分水嶺分割算法
>>Lim=watershed(temp);

>>em=Lim==0;
>>figure,imshow(em) %em=external marker,外部標記符

控制標記符分水嶺分割算法
結果顯示一片黑,進一步查看:

>> whos em
  Name        Size             Bytes  Class      Attributes

  em        253x251            63503  logical             

>> max(em(:))
ans =
     0

原因:距離變換後得到的一些孤立的亮區域,那些區域包含分水嶺脊線,而所有的黑色區域對應匯水盆地。em包含在所有亮區域內,不能連通。求出的分水嶺變換全爲1:沒找到合適的分水嶺脊線(不能形成對圖像有效分割的分水嶺脊線)。
實際上,應該對im2的補求分水嶺變換,這樣求得的分水嶺脊線就在米粒之間,這個作爲外部標記符。

下面對“擴展局部最小區域(im2)”的補求分水嶺變換:

>> temp=bwdist(~im2);figure,imshow(temp,[])

控制標記符分水嶺分割算法
和預料的一樣,目標區域爲匯水盆地。最亮的地方對應分水嶺脊線。

>> Lim=watershed(temp);em=Lim==0;figure,imshow(em)
控制標記符分水嶺分割算法 
這些脊線應該作爲外部標記纔對!

⑤仿二值圖像分水嶺分割的方法,將此區域疊加到原圖像上:

>> f(em)=255;figure,imshow(f,[])

控制標記符分水嶺分割算法
可看到,過分割現象已不存在了,但出現了一點誤分割(右下角處)。

⑥對於標記分水嶺方法來說,第⑤步應該修改爲:給出內部和外部標記後,就可以使用它們來修改梯度圖像——使用稱爲“強制最小”的過程。方法如下:

>> g2=imimposemin(g,im2 | em);%im2爲內部標記,em爲外部標記
>> L2=watershed(g2);

>> f2=f;f2(L2==0)=255;figure,imshow(f2,[])

 

控制標記符分水嶺分割算法
分割到的結果比較理想,但爲什麼會有一部分沒有被分割??
總結一下整個程序:

f=imread('rice_tophat.png');

h=fspecial('sobel');

fd=double(f);

g=sqrt(imfilter(fd,h,'replicate').^2+imfilter(fd,h','replicate').^2);

rm=imregionalmin(f);

im2=imextendedmin(f,45);%閾值要通過觀察來定

im2=~im2;

temp=bwdist(im2);

Lim=watershed(temp);em=Lim==0;

g2=imimposemin(g,im2|em);

L2=watershed(g2);

f2=f;f2(L2==0)=255;

figure,imshow(f2,[])

//要根據實際情況來定,如中間不一定要經過im2=~im2;的轉換。總體流程是這樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章