注:筆者水平有限,此博客目的爲學習記錄,方便以後複習。
9.1 預備知識
本節介紹一些集合理論中的基本概念,並討論MATLAB的邏輯運算符對於二值圖像的應用。
9.1.1 集合論中的基本概念
若(x,y)是Z^2中的整數,f是爲每對不同的座標(x,y)分配亮度值(即來源於實數集R中的實數)的映射,則函數f(x,y)稱爲數字圖像。
除去基本的交併運算外,形態學運算中通常還需要兩個運算符,這兩個運算符是特別針對於元素均爲像素座標的集合的,定義如下:
9.1.2 二值圖像、集合和邏輯運算符
一副二值圖像可以看成是x,y的二值函數,形態學理論中把二值圖像看成是其前景像素的集合(1值)。二值圖像間可以進行集合的交併運算,之後仍爲二值圖像;若A和B中的像素爲前景像素,運算後仍爲前景像素。
9.2 膨脹和腐蝕
9.2.1 膨脹
膨脹是在二值圖像中“加長”或“變粗”的操作。這種特殊的方式和變粗的程度由一個稱爲結構元素的集合控制。
膨脹運算的過程如下:結構元素的原點必須標明,之後,將該結構元素的原點在原圖像上平移,元素內有1與原圖像中的1重合時,結構元素原點所在的點變爲1值。
數學上,膨脹定義爲集合運算:
可使用imdilate()函數執行膨脹運算
A2 = imdilate(A,B);
膨脹可應用於圖像增強:
9.2.2 膨脹元素的分解
膨脹滿足結合律,因此,結構元素可以進行分解。又因爲計算膨脹所需要的時間正比於結構元素中非零元素的個數,因而可以通過對結構元素進行分解減少運算時間。
例如,一個55的全1結構元素,可以分解爲15的全1結構元素與5*1的全1結構元素相膨脹,速度可提升約2.5倍。
9.2.3 函數strel
函數strel用於構造各種形狀和大小的結構元素,其基本語法爲:
se = strel(shape,parameters)
其中,shape是指定希望形狀的字符串,parameters是指定形狀信息(如大小)的一列參數。
strel不顯示通常的MATLAB矩陣,而是返回一個稱爲strel對象的特殊量,顯示其鄰域、結構元素中值爲1的像素數、分解中的結構元素數以及分解中的結構元素中值爲1的總像素數。函數getsequence可用於提取並檢查分解其中的單個結構元素。
decomp = getsequence(se);
strel型對象,在imdilate處理過程中會自動使用分解信息來加快膨脹過程。
9.2.4 腐蝕
腐蝕“收縮”或“細化”二值圖像中的對象。收縮同樣由一個結構元素控制。
其運算過程如下圖所示:即只有完全匹配是才爲1,否則置0。
腐蝕的數學定義如下:
腐蝕用函數imerode來實現。當我們想要去除圖像中的細線,但想保留其他結構時,可以通過選取一個足夠小的結構元素來匹配中心方塊實現。
9.3 膨脹與腐蝕的組合
9.3.1 開運算和閉運算
A被B形態學開運算:A被B腐蝕後再用B來膨脹得到的腐蝕結果,即:
**應用:**形態學開運算完全刪除了不能包含結構元素的對象區域,平滑了對象的輪廓,斷開了狹窄的連接,去掉了細小的突出部分。
A被B的形態學閉運算與開運算相反,即先膨脹再腐蝕。
應用:形態學閉運算也會平滑對象的輪廓,但一般會將狹窄的缺口連接起來形成細長的彎口,並填充比結構元素小的洞。
形態學開運算與閉運算可用MATLAB工具箱函數imopen imclose實現。
C1 = imopen(A,B);
C2 = imclose(A,B);
A是一副二值圖像,B可用strel生成。
應用:
9.3.2 擊中或擊不中變換
擊中或擊不中變換用於識別像素的特定形狀,例如孤立的前景像素或線段的端點像素。定義如下:
擊中或擊不中變換由函數bwitmiss實現:
C = bwitmiss(A,B1,B2);
擊中或擊不中變換可用於定位:
9.3.3 使用查找表
當擊中或擊不中元素較小時,計算擊中或擊不中變換的較快方法是使用查找表(LUT)。這種方法是預先計算出每個可能鄰域形狀的像素值,然後把這些值存儲到一個表中,以便以後使用。
工具箱中提供兩個函數實現此功能。其中makelut基於一個提供給用戶的函數構造一個查找表,函數applylut則使用這個查找表來處理二值圖像。
例如,在上例中,使用makelut寫一個能接收33矩陣並返回一個單值的矩陣,並對每個可能的33矩陣調用512次,它以512個數的向量的形式返回。
在此我們編寫一個endpoints用於檢測邊緣點。
function g = endpoints(f);
persistent lut
if isempty(lut)
lut = makelut(@endpoint_fcn,3);
end
g = applylut(f,lut);
function is_end_point = endpoint_fcn(nhood)
is_end_point = nhood(2,2) & (sum(nhood(:)) == 2)
應用:
function out = conwaylaws(nhood)
num_neighbors = sum(nhood(:)) ~ nhood(2,2);
if nhood(2,2) == 1
if num_neighbors <= 1
out = 0;
else if num_neighbors >= 4
out = 0;
else
out = 1;
end
else
if num_neighbors == 3
out = 1;
else
out = 0;
end
end
lut = makelut(@conwaylaws,3); %使用上述函數調用makelut,可構建查找表
bw1 = [] %此處爲初始圖象
imshow(bw1,'n');
bw2 = applylut(bw1,lut);
imshow(bw2,'n');
bw3 = applylut(bw2,lut);
imshow(bw3,'n');
9.3.4 函數bwmorph
bwmorph函數可以執行膨脹、腐蝕、查找表等多種操作。
g = bwmorph(f,operation,n)
f爲輸入圖像,operation指定操作,n指定重複操作次數,當n爲Inf時表示重複操作直至不變。
9.4 標註連接分量
一個座標爲(x,y)的像素p有兩個水平和兩個垂直的相鄰像素,其集合記爲N4(p),稱爲四鄰域;同理,若是8個方向則稱爲八鄰域。若元素q屬於N4§,則稱p和q爲四鄰接;若元素q屬於N8§,則稱p和q八鄰接。
若在前景像素p和q之間存在一條完全由前景像素組成的4連接路徑,則稱這兩個前景像素爲4連接。若存在8連接路徑則稱爲8連接。對任意前景像素p,與其連接的所有前景像素的集合稱爲包含p的連接分量。
bwlabel函數可用於計算一副二值圖像中的所有連接分量。
[L num] = bwlabel(f,conn) #conn默認爲8
可通過該方法計算和顯示連接分量的質心
f = imread('123.jpg');
[L,n] = bwlabel(f);
[r,c] = find(L == 3) #將返回屬於第三個對象的所有像素的行索引和列索引
rbar = mean(r);
cbar = mean(c);
imshow(f)
hold on
for k = 1:n
[r,c] = find(L == k);
rbar = mean(r);
cbar = mean(c);
plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k'...'MarkerFaceColor','k','MarkerSize',10);
plot(cbar,rbar,'Marker','*','MarkerEdgeColor','w');
end
9.5 形態學重構
重構是一種涉及到兩幅圖像和一個結構元素的形態學變換。一幅圖像爲標記,是變換的開始點,另一幅圖像爲掩膜,用來約束變換過程,結構元素用於定義連接性。如下討論的B是一個大小爲3*3且值爲1的矩陣,其中心座標爲(2,2)。
可以用函數imreconstruct實現。
out = imreconstruct(marker,mask);
9.5.1 由重構做開運算
形態學開運算,先腐蝕去除小的對象,再膨脹恢復保留下來圖像的形狀,但其還原精度取決於形狀和結構元素之間的相似性。本節用重構作開運算,精度更高。
9.5.2 填充孔洞
g = imfill(f,'holes');
9.5.3 清除邊界對象
g = imclearborder(f,conn);
9.6 灰度圖像形態學
除了擊中或擊不中變換外,其他的二值形態學操作都可以擴展到灰度圖像上。、
9.6.1 膨脹和腐蝕
膨脹腐蝕可以組合使用。例如,從膨脹後的圖像減去腐蝕後的圖像可以產生一個“形態學梯度”,他是檢測圖像中局部灰度級變化的一種度量。
morph_grad = imsubtract(gd,ge);
9.6.2 開運算和閉運算
可以使用交替順序濾波使圖像更加平滑。(先開運算再閉運算或先閉運算再開運算)
fasf = f;
for k = 2:5
se = strel(disk,'k');
fasf = imclose(imopen(fasf,se),se);
end
頂帽變換:從原圖像中減去開運算後的圖像稱爲頂帽變換。
f = imtophat(f,se);
底帽變換:從原圖像中減去閉運算後的結果稱爲底帽變換。
f = imbothat(f,se);
應用:(1)二者一起使用可以用於增強對比度。
se = strel('disk',3);
g = imsubtract(imadd(f,imtophat(f,se)),imbothat(f,se))
(2)顆粒分析
確定一副圖像中顆粒大小分佈。對於形狀規則且亮於背景的顆粒,基本方法是應用不斷增大尺寸的形態學開運算。對於每一個開運算,開運算中所有像素值的和會被計算;該和有時稱爲圖像的表面積。下面是對半徑爲0到35的圓盤形開運算。
f = imread('123.jpg');
sumpixels = zeros(1,36);
for k = 0:35
se = strel('disk',k);
fo = imopen(f,se);
sumpixels(k+1) = sum(fo(:));
end
9.6.3 重構
應用:刪除複雜圖像的背景
#執行開運算重構——提取水平相鄰鍵之間的背景
f = imread('calculator.jpg');
f_bor = imreconstruct(imerode(f,ones(1,71)),f);
f_o = imopen(f,ones(1,71));
#頂帽重構
f_thr = imsubtract(f,f_obr);
f_th = imsubtract(f,f_o);
#通過使用一條短水平線執行開運算重構來消除鍵右側的垂直反射光
g_obr = imreconstruct(imerode(f_thr,ones(1,11)),f_thr);
#膨脹恢復被誤消的字符
g_obrd = imdilate(g_obr,ones(1,21));
#將f_thr作爲掩膜,將min(g_obrd,f_thr)作爲標記,進行重構
f2 = imreconstruct(min(g_obrd,f_thr),f_thr);