所謂的最終腐蝕並不是把圖像不斷腐蝕直到一片黑為止,那樣還有什么意思呢。
最終腐蝕的意思是連續腐蝕過程中連通子區域消失前所有剩余部分的並。
看下圖有一個連通區域:
那么最終腐蝕就是把圖像不斷腐蝕到只剩圓環最中間的白色區域為止。如下:
所以一般最終腐蝕之后,如果再腐蝕一下,那么圖像就全沒了。
最終腐蝕的通常算法會先對原圖像使用距離變換,然后求區域極大值。不過這種方法怎么說呢,速度倒是快,不過我實驗了很多次,求得的結果很不穩定。
所以我就自己開發了一個算法,雖然有些慢,不過很穩定。
1.首先對原圖像進行連通區域標記。
2.對標記后圖像不斷進行腐蝕,每腐蝕一次,重新標記連通區域。
3.每腐蝕並且標記一次之后,檢查腐蝕后的圖像是否有哪一個標記的區域消失了,如果消失了,那么就把消失這一區域的最后一次出現的區域恢復。
4.直到下次腐蝕和這次腐蝕結果一樣,程序結束。
運行效果如下:
原圖:
最終腐蝕:
matlab代碼如下:
clear all; close all; clc; img=imread('te.png'); img=img>128; imshow(img); [m n]=size(img); imgn=zeros(m,n); preimg=imgn; se= strel('square',3); while sum(sum(preimg-img))~=0 preimg=img; img=img>0; [img label]=liantong(img); %標記不同區域,label是區域個數 imgn=imerode(img,se); %腐蝕之后是否有哪個被標記的區域消失了 Hist=zeros(1,label); for i=1:m for j=1:n if imgn(i,j)~=0 Hist(imgn(i,j))=imgn(i,j); end end end %統計消失區域的標號 H=[]; for i=1:label if Hist(i)==0 H=[H i]; end end %如果這個區域消失了,那么再把這個區域恢復過來 if ~isempty(H) l=length(H); for i=1:m for j=1:n for k=1:l if img(i,j)==H(k) imgn(i,j)=img(i,j); end end end end end img=imgn; end figure; imshow(imdilate(imgn>0,se)); %再膨脹一下好看
有了最終腐蝕與條件膨脹,那么分水嶺算法的實現也就近在眼前了。