二值圖像中的形態(tài)學(xué)應(yīng)用
擊中擊不中
形態(tài)學(xué)擊中擊不中變換常用于圖像中某種特定形狀的精確定位,是一種形狀檢測的基本工具,可以表示為A?S=(AΘS1)?(AcΘS2),其中S1與S2沒有任何交集,且S1和S2的并集為S,也就是說,利用S1腐蝕A,再用S1的補(bǔ)集S2腐蝕A的補(bǔ)集Ac,再取二者的交集。
matlab中進(jìn)行擊中擊不中變換的函數(shù)為bwhitmiss();
Ihm=bwhitmiss(I,S1,S2);
I為輸入圖像,S1和S2為前面所說的結(jié)構(gòu)元素,Ihm為完成擊中擊不中變換后的結(jié)果圖像。
邊界提取與跟蹤
通過邊界提取算法可以得到物體的邊界輪廓;而邊界跟蹤算法在提取邊界的同時還能依次記錄下邊界的像素位置信息。
邊界提取
對于二值圖像,我們可以很明顯的看到,如果發(fā)現(xiàn)其中一個黑點(diǎn)的8個鄰域內(nèi)都是黑點(diǎn),那么這個點(diǎn)就是圖像的內(nèi)部點(diǎn),而我們想要得到這個圖像的邊界,只需要刪除它所有的內(nèi)部點(diǎn)即可,因此我們可以逐行進(jìn)行掃描,一旦發(fā)現(xiàn)內(nèi)部點(diǎn),就進(jìn)行刪除,實(shí)際上,這就相當(dāng)于是用一個3×3的正方形結(jié)構(gòu)元素對圖像進(jìn)行腐蝕,腐蝕所得到的圖像就是這個圖像的內(nèi)部點(diǎn)構(gòu)成的圖像,而后再對其進(jìn)行刪除,就留下了邊界元素。
tip:3×3十字架進(jìn)行腐蝕的得到的邊界是8連通邊界,正方形則是4連通邊界。
matlab實(shí)現(xiàn):
>> I=imread('head_portrait.bmp');
>> se=strel('square',3);
>> Ie=imerode(I,se);
>> Iout=I-Ie;
>> subplot(1,3,1),imshow(I);
>> subplot(1,3,2),imshow(Ie);
>> subplot(1,3,3),imshow(Iout);

邊界跟蹤算法
我們想要依次記錄下邊界的各個像素點(diǎn),首先我們得找到其中一點(diǎn),然后再從這個點(diǎn)出發(fā),按照某種規(guī)則順序,依次找到下一點(diǎn),最終回到初始點(diǎn),這樣我們就記錄下了整條邊界。
所以,我們先按照從左到右從上到下的順序掃描圖像,就可以找到圖像最左上的點(diǎn),可想而知,這個點(diǎn)的左側(cè)和上側(cè)都不可能存在點(diǎn),因此我們可以設(shè)定從左下開始跟蹤,如果這點(diǎn)是黑點(diǎn),則判定為時邊界點(diǎn),若不是,則在此跟蹤方向上逆時針旋轉(zhuǎn)45度繼續(xù)探查,直到找到邊界點(diǎn)為止,找到邊界點(diǎn)后,在當(dāng)前方向的基礎(chǔ)上順時針90度,用上述方法進(jìn)行探查,尋找下一個邊界點(diǎn)。
如圖所示

tip:這種算法只能用于跟蹤圖像的外輪廓,若圖像帶有孔洞,并不能跟蹤孔洞的輪廓。
區(qū)域填充
tip:4連通邊界內(nèi)部區(qū)域是8連通的,8連通邊界內(nèi)部區(qū)域則是4連通的。因此,填充4連通邊界的結(jié)構(gòu)元素應(yīng)選擇3×3正方形,而填充8連通邊界的結(jié)構(gòu)元素應(yīng)該選擇3×3十字架結(jié)構(gòu)。
簡要描述一下,已知某一8連通邊界和邊界內(nèi)部的某個點(diǎn),然后從該點(diǎn)開始填充整個邊界包圍的區(qū)域,這一過程也可以稱作是“種子填充”。
十字架結(jié)構(gòu)元素可以保證只要種子點(diǎn)在邊界內(nèi),所膨脹后的結(jié)構(gòu)都不會產(chǎn)生邊界以外的點(diǎn)(最多落在邊界上),這樣,我們只需要用膨脹后的圖像與邊界的補(bǔ)圖像進(jìn)行相交,就能把膨脹限制在邊界內(nèi)部,直到我們的膨脹圖像B填充滿邊界A,這時候取AB并集,就是最終的區(qū)域填充結(jié)果。
連通分量提取
基于形態(tài)學(xué)的連通分量提取操作和區(qū)域填充有點(diǎn)相似,以8連通的圖像進(jìn)行比方,假設(shè)圖像A的內(nèi)部有多個連通分量,B為連通分量A1內(nèi)某點(diǎn),其他連通分量自然與A1起碼有一個像素寬的空白縫隙,3×3的結(jié)構(gòu)元素保證了只要B在A1的內(nèi)部,每次膨脹都不會產(chǎn)生在其他連通區(qū)域范圍內(nèi)的點(diǎn),然后用每次膨脹的結(jié)果圖像與A進(jìn)行相交,就能把膨脹限制在A1的內(nèi)部,最終使得B充滿A1,也就完成了連通分量A1的提取。
tip:提取連通分量結(jié)構(gòu)元素(8連通使用3×3正方形,4連通使用3×3十字形)
matlab中有專門的函數(shù)bwlabel()進(jìn)行實(shí)現(xiàn),調(diào)用語法如下:
[L num]=bwlabel(Ibw,conn)
其中,Ibw為輸入的二值圖像,conn為可選參數(shù),指明要提取的連通分量是4連通還是8連通,一般默認(rèn)為8,L為標(biāo)注圖像,num為連通分量的個數(shù)。
示例:matlab實(shí)現(xiàn)在人臉局部定位嘴的中心
I = imread('mouth.bmp'); %讀入圖像
Id = im2double(I);
figure, imshow(Id) % 得到8.24(a)
Ibw = im2bw(Id, 0.38); % 以0.38為閾值二值化
Ibw = 1 - Ibw; %為在Matlab中進(jìn)行處理,將圖像反色
figure, imshow(Ibw) % 得到8.24(b)
hold on
[L, num] = bwlabel(Ibw, 8); % 標(biāo)注連通分量
disp(['圖中共有' num2str(num) '個連通分量'])
% 找出最大的連通分量(嘴)
max = 0; % 當(dāng)前最大連通分量的大小
indMax = 0; % 當(dāng)前最大連通分量的索引
for k = 1:num
[y x] = find(L == k); % 找出編號為k的連通區(qū)的行索引集合y和列索引集合x
nSize = length(y); %計算該連通區(qū)中的像素數(shù)目
if(nSize > max)
max = nSize;
indMax = k;
end
end
if indMax == 0
disp('沒有找到連通分量')
return
end
% 計算并顯示最大連通分量(嘴)的中心
[y x] = find(L == indMax);
yMean = mean(y);
xMean = mean(x);
plot(xMean, yMean, 'Marker', 'o', 'MarkerSize', 14, 'MarkerEdgeColor', 'w', 'MarkerFaceColor', 'w');
plot(xMean, yMean, 'Marker', '*', 'MarkerSize', 12, 'MarkerEdgeColor', 'k'); % 得到8.24(c)


tip:二值化處理,小于閾值的設(shè)定為白色(255),大于閾值的設(shè)定為黑色(0)。
示例:細(xì)菌計數(shù),對顯微鏡視野內(nèi)的細(xì)菌進(jìn)行計數(shù)。
>> I=imread('bw_bacteria.bmp');
>> [L, num]=bwlabel(I,8);
>> num
num =
22
>> Idil=imdilate(I,ones(3,3));
>> subplot(1,2,1),imshow(I),title('經(jīng)過二值化后的');
>> subplot(1,2,2),imshow(Idil),title('經(jīng)過膨脹后的');
>> [L, num]=bwlabel(Idil,8);
>> num
num =
21
我們可以看到,由于二值化的閾值選取不當(dāng),導(dǎo)致某一個細(xì)菌在二值化后出現(xiàn)了“斷裂”,容易給計數(shù)造成困擾,因此對該圖像進(jìn)行一個3×3結(jié)構(gòu)元素的膨脹,膨脹后發(fā)現(xiàn)斷裂接合了,則得到了準(zhǔn)確的計數(shù)。
