140 likes | 655 Views
第 12 章 形狀與邊界. 12.1 導論 12.2 鏈碼與形狀數 12.3 傅利葉描述元. 12.1 導論. 本章會著重在檢視物體形狀的方法上 描述形狀的正式方法稱為形狀描述元 ( shape descriptors ) 精確的的定義某項物體的形狀稱為形狀表示法 ( shape representation ) 12.2 鏈碼與形狀數 鏈碼 (chain code) 的概念相當直接 : 沿著物體的邊界行進,並記下行進的方向即可,這些方向便是鏈碼. 要使用 MATLAB 函數求得鏈碼 , 我們可以寫一個小函數來完成
E N D
第12章 形狀與邊界 12.1 導論 12.2 鏈碼與形狀數 12.3 傅利葉描述元
12.1 導論 • 本章會著重在檢視物體形狀的方法上 • 描述形狀的正式方法稱為形狀描述元(shape descriptors) • 精確的的定義某項物體的形狀稱為形狀表示法(shape representation) 12.2 鏈碼與形狀數 • 鏈碼(chain code)的概念相當直接:沿著物體的邊界行進,並記下行進的方向即可,這些方向便是鏈碼
要使用MATLAB函數求得鏈碼,我們可以寫一個小函數來完成要使用MATLAB函數求得鏈碼,我們可以寫一個小函數來完成 假設二元數位影像im包含了單一物體。我們可以使用下列MATLAB指令找出左上角像素 >>[x y]=find(im==1); >>x=min(x); >>imx=im(x,:); >>y=min (imx); 我們可以將這些數值放入一個矩陣 >>n=[0 1;-1 0;0 -1;1 0]; 給定一個方向dir,鍵入下列指令 這樣就會從正確的方向掃描影像im在位置(x,y)的鄰域。鄰域掃描完,所有的數值都會放入一個小向量tt >> newdir=mod(dir+3,4); >>fori=0:3, >>j=mod(newdir+i,4)+1; >>tt(i+1)=image(x+n(j,1),y+n(j,2)); 用下列指令找出第一個非零的數值: >>d=min(find(tt==1)); 更新dir,目前像素的位置變為: >>dir=mod(newdir+d-1,4); >>x=x+n(dir+1,1);y=y+n(dir+1,2); 執行的同時,最新的dir值便存入一個向量,此項量將會成為最後的鏈碼
前一節所討論的鏈碼定義會產生兩個問題: 1.鏈碼會因起點像素而改變 2.鏈碼會因為物體的方位而改變 鏈碼正規化概念如下:將鏈碼沿著圓型排列,將讀取的起始點設為最小整數位置,得出的結果便是物體的正規化鏈碼 首先討論第一個問題 假設物體由3x3方形構成: >>a=zeros(5,5);a(2:4,2:4)=1 a = 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 >> c=chaincode4(a) c = 3 3 0 0 1 1 2 2 將鏈碼排列成圓形 12.2.1 鏈碼的正規化
產生循環矩陣 • >> m=c; • >>for i=2:8,m=[m;[m(i-1,8),m(i-1,1:7)]];end • >>m m = 3 3 0 0 1 1 2 2 2 3 3 0 0 1 1 2 2 2 3 3 0 0 1 1 1 2 2 3 3 0 0 1 1 1 2 2 3 3 0 0 0 1 1 2 2 3 3 0 0 0 1 1 2 2 3 3 3 0 0 1 1 2 2 3 • 使用函數sortrows,找出最小整數值的列 • >> ms=sortrows(m) • ms = 0 0 1 1 2 2 3 3 0 1 1 2 2 3 3 0 1 1 2 2 3 3 0 0 1 2 2 3 3 0 0 1 2 2 3 3 0 0 1 1 2 3 3 0 0 1 1 2 3 0 0 1 1 2 2 3 3 3 0 0 1 1 2 2 • 正規化鏈碼剛好就是第一列 • >> ms(1,:) ans = 0 0 1 1 2 2 3 3
12.2.2形狀數 • 現在來討論如何解決鏈碼會因物體方位而改變的問題 • 舉例來說,一個簡單的L型: • >>L=zeros(7,6);L(2:6,2:3)=1;L(5:6,4:5)=1 • L = 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0
求其鏈碼 • c=chaincode4(L) • c = 3 3 3 3 0 0 0 1 2 2 1 1 1 2 • 將鏈碼正規化 • >> normalize(c) • ans = 0 0 0 1 2 2 1 1 1 2 3 3 3 3 • 假設我們旋轉物體至不同方位(使用函數rot函數,將矩陣旋轉90度): • >> L2=rot90(L) • L2 = 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0
求此新方位的正規化鏈碼: • >> c2=chaincode4(L2) • c2 = 3 3 2 2 2 3 0 0 0 0 1 1 1 2 • >> normalize(c2) • ans = 0 0 0 0 1 1 1 2 3 3 2 2 2 3 • 即使經過正規化,鏈碼仍舊不同。 • 要解決這個問題,可以取鏈碼之間的差值,再將差值正規化,求出形狀數 • 使用MATLAB求出形狀數。給定鏈碼c,產生循環平移編碼,將第一個元素移至最後: • >> c=chaincode4(a) • c = 3 3 0 0 1 1 2 2 • >> c1=[c(2:8) c(1)] • c1 = 3 0 0 1 1 2 2 3
將上述兩向量相減,取mod4 • >> mod(c1-c,4) • ans = 0 1 0 1 0 1 0 1 • 上述編碼正規化後便是物體的形狀數。使用此函數檢視L型及旋轉後的形狀。 • >> c=chaincode4(L); • >>lc=length(c); • >>c1=[c(2:lc) c(1)]; • >>mod(c1-c,4) • ans = 0 0 0 1 0 0 1 1 0 3 0 0 1 1 • 上面結果已正規化。
檢視L2: • >> c=chaincode4(L2); • >>lc=length(c); • >>c1=[c(2:lc) c(1)]; • >>mod(c1-c,4) • ans = • 0 3 0 0 1 1 0 0 0 1 0 0 1 1 • 將其正規化: • >>normalize(ans) • ans= • 0 0 0 1 0 0 1 1 0 3 0 0 1 1 • 與L的結果一樣
12.3 傅利葉描述元 • 概念如下:我們沿著物體邊界行走,但並非記下方向,而是記下邊界座標。所有的座標(x,y)會轉換為一列複數z=x+yi。而這列複數經過傅利葉轉換的結果則稱為該物體的傅利葉描述元(Fourier descriptor) • 使用傅利葉描述元的好處在於,只要根據轉換的前面幾項,就可以辨別物體或進行分類 • 函數chaincode4.m可以簡單的修改為boundary4.m,將下列指令 cc=[cc,dir];x=x+n(dir+1,1);y=y+n(dir+1,2); 換為 x=x+n(dir+1,1);y=y+n(dir+1,2); cc=[cc,x y];
如此一來,變數cc包含了邊界像素值。假設函數已經修改並執行如下:如此一來,變數cc包含了邊界像素值。假設函數已經修改並執行如下: >>a=zeros(5,5);a(2:4,2:4)=1 a = 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 >>b=boundary4(a) b= 3 2 4 2 4 3 4 4 3 4 2 4 2 3 2 2 將數值轉換為複數: >>c=complex(a(:,1),a(:,2)) c = 3.0000+ 2.0000i 4.0000+ 2.0000i 4.0000+ 3.0000i 4.0000+ 4.0000i 3.0000+ 4.0000i 2.0000+ 4.0000i 2.0000+ 2.0000i 2.0000+ 2.0000i
然後畫出來: >>plot(c,'o'),axis([1,5,1,5]),axis equal 進行傅利葉轉換,然後擷取其中幾項: >> f=fft(c) f = 24.0000 + 24.0000i 0 - 9.6569i 0 0 0 0 + 1. 6569i 0 0 >>f1=zeros(size(f)); >>f1(1:2)=f(1:2); >>plot(ifft(f1),'o'),axis([1.0,5.0,1.0,5.0]),axis square 結果如圖12.2所示。可發現下列幾點: 1.c經過傅利葉轉換後只有三項不為零 2.只要知道轉換結果的其中兩項就可獲得對物體的形狀、大小對稱性的概念。 3.即使形狀大幅度改變,例如方形變圓形,許多形狀描述元仍只有小幅變動 圖12.11 邊界像素 圖12.12 使用傅利葉描述元求邊界 近似值