二值圖像中的形態(tài)學(xué)應(yīng)用
擊中擊不中
形態(tài)學(xué)擊中擊不中變換常用于圖像中某種特定形狀的精確定位涮瞻,是一種形狀檢測的基本工具,可以表示為A?S=(AΘS1)?(AcΘS2)假褪,其中S1與S2沒有任何交集署咽,且S1和S2的并集為S,也就是說生音,利用S1腐蝕A宁否,再用S1的補集S2腐蝕A的補集Ac,再取二者的交集缀遍。
matlab中進行擊中擊不中變換的函數(shù)為bwhitmiss()慕匠;
Ihm=bwhitmiss(I,S1,S2);
I為輸入圖像,S1和S2為前面所說的結(jié)構(gòu)元素瑟由,Ihm為完成擊中擊不中變換后的結(jié)果圖像絮重。
邊界提取與跟蹤
通過邊界提取算法可以得到物體的邊界輪廓;而邊界跟蹤算法在提取邊界的同時還能依次記錄下邊界的像素位置信息歹苦。
邊界提取
對于二值圖像青伤,我們可以很明顯的看到,如果發(fā)現(xiàn)其中一個黑點的8個鄰域內(nèi)都是黑點殴瘦,那么這個點就是圖像的內(nèi)部點狠角,而我們想要得到這個圖像的邊界,只需要刪除它所有的內(nèi)部點即可蚪腋,因此我們可以逐行進行掃描丰歌,一旦發(fā)現(xiàn)內(nèi)部點,就進行刪除屉凯,實際上立帖,這就相當于是用一個3×3的正方形結(jié)構(gòu)元素對圖像進行腐蝕,腐蝕所得到的圖像就是這個圖像的內(nèi)部點構(gòu)成的圖像悠砚,而后再對其進行刪除晓勇,就留下了邊界元素。
tip:3×3十字架進行腐蝕的得到的邊界是8連通邊界,正方形則是4連通邊界绑咱。
matlab實現(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);
邊界跟蹤算法
我們想要依次記錄下邊界的各個像素點描融,首先我們得找到其中一點铝噩,然后再從這個點出發(fā),按照某種規(guī)則順序窿克,依次找到下一點骏庸,最終回到初始點,這樣我們就記錄下了整條邊界让歼。
所以敞恋,我們先按照從左到右從上到下的順序掃描圖像,就可以找到圖像最左上的點谋右,可想而知硬猫,這個點的左側(cè)和上側(cè)都不可能存在點,因此我們可以設(shè)定從左下開始跟蹤改执,如果這點是黑點啸蜜,則判定為時邊界點,若不是辈挂,則在此跟蹤方向上逆時針旋轉(zhuǎn)45度繼續(xù)探查衬横,直到找到邊界點為止,找到邊界點后终蒂,在當前方向的基礎(chǔ)上順時針90度蜂林,用上述方法進行探查,尋找下一個邊界點拇泣。
如圖所示
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)部的某個點臭杰,然后從該點開始填充整個邊界包圍的區(qū)域,這一過程也可以稱作是“種子填充”谚中。
十字架結(jié)構(gòu)元素可以保證只要種子點在邊界內(nèi)渴杆,所膨脹后的結(jié)構(gòu)都不會產(chǎn)生邊界以外的點(最多落在邊界上)射窒,這樣,我們只需要用膨脹后的圖像與邊界的補圖像進行相交将塑,就能把膨脹限制在邊界內(nèi)部,直到我們的膨脹圖像B填充滿邊界A蝌麸,這時候取AB并集点寥,就是最終的區(qū)域填充結(jié)果。
連通分量提取
基于形態(tài)學(xué)的連通分量提取操作和區(qū)域填充有點相似来吩,以8連通的圖像進行比方敢辩,假設(shè)圖像A的內(nèi)部有多個連通分量,B為連通分量A1內(nèi)某點弟疆,其他連通分量自然與A1起碼有一個像素寬的空白縫隙戚长,3×3的結(jié)構(gòu)元素保證了只要B在A1的內(nèi)部,每次膨脹都不會產(chǎn)生在其他連通區(qū)域范圍內(nèi)的點怠苔,然后用每次膨脹的結(jié)果圖像與A進行相交同廉,就能把膨脹限制在A1的內(nèi)部,最終使得B充滿A1柑司,也就完成了連通分量A1的提取迫肖。
tip:提取連通分量結(jié)構(gòu)元素(8連通使用3×3正方形,4連通使用3×3十字形)
matlab中有專門的函數(shù)bwlabel()進行實現(xiàn)攒驰,調(diào)用語法如下:
[L num]=bwlabel(Ibw,conn)
其中蟆湖,Ibw為輸入的二值圖像,conn為可選參數(shù)玻粪,指明要提取的連通分量是4連通還是8連通隅津,一般默認為8,L為標注圖像劲室,num為連通分量的個數(shù)伦仍。
示例:matlab實現(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中進行處理,將圖像反色
figure, imshow(Ibw) % 得到8.24(b)
hold on
[L, num] = bwlabel(Ibw, 8); % 標注連通分量
disp(['圖中共有' num2str(num) '個連通分量'])
% 找出最大的連通分量(嘴)
max = 0; % 當前最大連通分量的大小
indMax = 0; % 當前最大連通分量的索引
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)。
示例:細菌計數(shù)蹲缠,對顯微鏡視野內(nèi)的細菌進行計數(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ǎo)致某一個細菌在二值化后出現(xiàn)了“斷裂”娜谊,容易給計數(shù)造成困擾,因此對該圖像進行一個3×3結(jié)構(gòu)元素的膨脹斤讥,膨脹后發(fā)現(xiàn)斷裂接合了纱皆,則得到了準確的計數(shù)湾趾。