目標內邊界的像素全都在目標里面,目標外邊界的像素全都不在目標上,是包圍着目標的。
二值圖像內外邊界的計算都是有兩種方法的,所以一共是4種算法,不過實際用到跟蹤的只有一個而已。
首先是內邊界跟蹤:
第一種方法不是跟蹤方法。步驟是先對原圖像腐蝕,然后用原圖像減去腐蝕后的圖像就得到邊界了。
第二種方法是跟蹤方法。步驟如下:
1.遍歷圖像。
2.標記第一個遇見像素塊的前景像素(i,j)。
3.對這個像素周圍八鄰域逆時針搜索,如果搜索到周圍有前景像素,那么更新坐標(i,j)為(i',j'),並標記。
4.不斷執行第3步直到再次遇見此像素塊第一次標記的像素。
5.繼續執行第1步。
然后是外邊界跟蹤:
第一種方法和求內邊界第一種方法類似。先對原圖像進行膨脹,然后用膨脹后的圖像減去原圖像即可。
第二種也不算跟蹤方法,只是標記算法而已。就是將圖像中前景像素周圍的非前景像素標記一下就行了。
效果如下:
原圖:
內邊界:
外邊界:
matlab程序如下:
內邊界:
clear all; close all; clc; img=imread('rice.png'); img=img>128; imshow(img); [m n]=size(img); imgn=zeros(m,n); %邊界標記圖像 ed=[-1 -1;0 -1;1 -1;1 0;1 1;0 1;-1 1;-1 0]; %從左上角像素,逆時針搜索 for i=2:m-1 for j=2:n-1 if img(i,j)==1 && imgn(i,j)==0 %當前是沒標記的白色像素 if sum(sum(img(i-1:i+1,j-1:j+1)))~=9 %塊內部的白像素不標記 ii=i; %像素塊內部搜尋使用的坐標 jj=j; imgn(i,j)=2; %本像素塊第一個標記的邊界,第一個邊界像素為2 while imgn(ii,jj)~=2 %是否沿着像素塊搜尋一圈了。 for k=1:8 %逆時針八鄰域搜索 tmpi=ii+ed(k,1); %八鄰域臨時坐標 tmpj=jj+ed(k,2); if img(tmpi,tmpj)==1 && imgn(tmpi,tmpj)~=2 %搜索到新邊界,並且沒有搜索一圈 ii=tmpi; %更新內部搜尋坐標,繼續搜索 jj=tmpj; imgn(ii,jj)=1; %邊界標記圖像該像素標記,普通邊界為1 break; end end end end end end end figure; imgn=imgn>=1; imshow(imgn,[]); %不過要是真取二值圖像內邊界,通常是原圖減去其腐蝕圖就行了 se = strel('square',3); imgn=img-imerode(img,se); figure; imshow(imgn)
外邊界:
clear all; close all; clc; img=imread('rice.png'); img=img>128; imshow(img); [m n]=size(img); imgn=zeros(m,n); %邊界標記圖像 ed=[-1 -1;0 -1;1 -1;1 0;1 1;0 1;-1 1;-1 0]; %從左上角像素判斷 for i=2:m-1 for j=2:n-1 if img(i,j)==1 %如果當前像素是前景像素 for k=1:8 ii=i+ed(k,1); jj=j+ed(k,2); if img(ii,jj)==0 %當前像素周圍如果是背景,邊界標記圖像相應像素標記 imgn(ii,jj)=1; end end end end end figure; imshow(imgn,[]); %不過要是真取二值圖像外邊界,通常是原圖膨脹圖減去原圖就行了 se = strel('square',3); imgn=imdilate(img,se)-img; figure; imshow(imgn)