1. 程式人生 > >【數字影象處理】作業二 邊緣檢測與追蹤

【數字影象處理】作業二 邊緣檢測與追蹤

作業二 邊緣檢測與追蹤

吳政億 151220129 [email protected]

(南京大學 電腦科學與技術系, 南京 210093)

邊緣檢測

在邊緣檢測中,我使用了sobelrobertsprewittmarr作為運算元,對每一種運算元調參,並進行了比較。

主體框架(marr單獨介紹)

my_edge.m中13~24行分別對應三個運算元的high與low引數,大於high的被識別為邊界,小於low的則被識別為非邊界,在low~high之間的則根據鄰域是否有邊界來決定是否是邊界。這樣可以排除一部分的孤立點與噪聲。

function output
= my_edge(input_image)
input_image=im2double(input_image); [M,N]=size(input_image); SX = zeros(M,N); SY = zeros(M,N); % %sobel % high = 0.3; % moon:0.3 others:1.5 % low = 0.2; % moon:0.2 others:0.5 % %roberts % high = 0.09; % moon:0.09 key:0.4 cap:0.5 % low = 0.05; % moon:0.05 others:0.2
%prewitt high = 0.25; % moon:0.25 others:0.8 low = 0.1; % moon:0.1 others:0.5 gray_image = zeros(M-2,N-2); for i=2:M-1 for j = 2:N-1 % gray_image(i-1,j-1) = sobel(input_image(i-1,j-1),input_image(i-1,j),input_image(i-1,j+1),input_image(i,j-1),input_image(i,j),input_image(i,j+1),input_image(i+1,j-1),input_image(i+1,j),input_image(i+1,j+1));
% gray_image(i-1,j-1) = roberts(input_image(i-1,j-1),input_image(i-1,j),input_image(i-1,j+1),input_image(i,j-1),input_image(i,j),input_image(i,j+1),input_image(i+1,j-1),input_image(i+1,j),input_image(i+1,j+1)); gray_image(i-1,j-1) = prewitt(input_image(i-1,j-1),input_image(i-1,j),input_image(i-1,j+1),input_image(i,j-1),input_image(i,j),input_image(i,j+1),input_image(i+1,j-1),input_image(i+1,j),input_image(i+1,j+1)); end end edge_image = zeros(M-2,N-2); for i = 1:M-2 for j = 1:N-2 if gray_image(i,j) > high edge_image(i,j) = 1; elseif gray_image(i,j) < low edge_image(i,j) = 0; elseif i==1 || j ==1 || i == M-2 || j == N-2 edge_image(i,j) = 0; else edge_image(i,j) = -1; end end end for i = 2:M-3 for j = 2:N-3 if edge_image(i,j) == -1 if edge_image(i-1,j-1) == 1 ||edge_image(i-1,j) == 1 ||edge_image(i-1,j+1) == 1 ||edge_image(i,j-1) == 1 ||edge_image(i,j+1) == 1 ||edge_image(i+1,j-1) == 1 ||edge_image(i+1,j) == 1 ||edge_image(i+1,j+1) == 1 edge_image(i,j) = 1; else edge_image(i,j) = 0; end end end end output = logical(edge_image);

sobel運算元

function sobel_value = sobel(v1,v2,v3,v4,v5,v6,v7,v8,v9)
    SX= -v1+v3-2*v4+2*v6-v7+v9;
    SY= v1+2*v2+v3-v7-2*v8-v9;
    sobel_value = sqrt(SX^2 + SY^2);

sobel-2018423 sobel2-2018423 sobel3-2018423 sobel4-2018423

roberts運算元

function roberts_value = roberts(v1,v2,v3,v4,v5,v6,v7,v8,v9)
    SX= abs(v9-v5);
    SY= abs(v6-v8);
    roberts_value = SX + SY;

roberts-2018423 roberts2-2018423 roberts3-2018423 roberts4-2018423

prewitt運算元

function prewitt_value = prewitt(v1,v2,v3,v4,v5,v6,v7,v8,v9)
    SX= -v1+v3-v4+v6-v7+v9;
    SY= v1+v2+v3-v7-v8-v9;
    prewitt_value = sqrt(SX^2 + SY^2);

prewitt-2018423 prewitt2-2018423 prewitt3-2018423 prewitt4-2018423

Marr運算元

先對影象進行復制外邊界的值來擴充套件的卷積,然後通過零交叉點判斷邊緣,最後用線性插值的方法估計邊緣位置。

function output = my_edge_marr(input_image)
% input:gray image output:image edge logical
% marr
[m,n] = size(input_image);
e = false(m,n);
sigma = 2.5;
row = 2:m-1; 
col=2:n-1;
op = fspecial('log',ceil(sigma*3) * 2 + 1,sigma);

op = op - sum(op(:))/numel(op); % make the op to sum to zero
b = imfilter(input_image,op,'replicate');

thresh = 0.75 * sum(abs(b(:)),'double') / numel(b);

% Look for the zero crossings
[r,c] = find(( b(row,col) < 0 & b(row,col+1) > 0 & abs( b(row,col)-b(row,col+1) ) > thresh )...
    |(b(row,col-1) > 0 & b(row,col) < 0 & abs( b(row,col-1)-b(row,col) ) > thresh)...
    |(b(row,col) < 0 & b(row+1,col) > 0 & abs( b(row,col)-b(row+1,col) ) > thresh)...
    |(b(row-1,col) > 0 & b(row,col) < 0 & abs( b(row-1,col)-b(row,col) ) > thresh));   
e((r+1) + c*m) = 1;

% check to see if there are any points where the LoG was precisely zero:
[rz,cz] = find( b(row,col)==0 );
if ~isempty(rz)
    zero = (rz+1) + cz*m;   % Linear index for zero points
    zz = ((b(zero-1) < 0 & b(zero+1) > 0 & abs( b(zero-1)-b(zero+1) ) > 2*thresh)...
        |(b(zero-1) > 0 & b(zero+1) < 0 & abs( b(zero-1)-b(zero+1) ) > 2*thresh)...
        |(b(zero-m) < 0 & b(zero+m) > 0 & abs( b(zero-m)-b(zero+m) ) > 2*thresh)...
        |(b(zero-m) > 0 & b(zero+m) < 0 & abs( b(zero-m)-b(zero+m) ) > 2*thresh));     
    e(zero(zz)) = 1;
end
output = e;
end

marr-2018426 marr2-2018426 marr3-2018426 marr4-2018426

四者對比

Roberts運算元定位比較精確,但由於不包括平滑,所以對於噪聲比較敏感。Prewitt運算元和Sobel運算元都是一階的微分運算元,而前者是平均濾波,後者是加權平均濾波且檢測的影象邊緣可能大於2個畫素。這兩者對灰度漸變低噪聲的影象有較好的檢測效果,但是對於混合多複雜噪聲的影象,處理效果就不理想了。PrewittSobel運算元比Roberts 效果要好一些,因為前兩者參考了周圍8個畫素的灰度值,得到的資訊更廣。

Marr運算元相比與上面三種非常突出,因為他考慮了梯度等因素,但是相比之下他被噪聲影響的更為明顯。

邊緣連結

由於邊緣連結的傳入引數是一個二值影象,我應用一個佇列將初始點入列,然後應用四鄰域與八鄰域兩種情況分別對其作邊緣連結,並返回所有連通分支上的點。 定義一個neighbour用來運算pix,即他的八/四鄰域所有點座標。

function output = my_edgelinking(binary_image, row, col)
    [M,N]=size(binary_image);

    tmp=[];
    queue_head=1;
    queue_tail=1;
    neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1];  %8-neighbourhood
%     neighbour=[-1 0;1 0;0 1;0 -1];     %4-neighbourhood
    q{queue_tail}=[row col];
    queue_tail=queue_tail+1;
    [ser1 , ~]=size(neighbour);
    num = 1;
    while queue_head~=queue_tail
        pix=q{queue_head};
        tmp(num,1)=pix(1,1);
        tmp(num,2)=pix(1,2);
        num = num + 1;
        for i=1:ser1
            pix1=pix+neighbour(i,:);
            if pix1(1)>=1 && pix1(2)>=1 &&pix1(1)<=M && pix1(2)<=N
                if binary_image(pix1(1),pix1(2)) == true
                    binary_image(pix1(1),pix1(2)) = false;
                    q{queue_tail}=[pix1(1) pix1(2)];
                    queue_tail=queue_tail+1;

                end      
            end
        end
        queue_head=queue_head+1;
    end
    output = tmp;

trace_126_232-2018423 trace_58_68-2018423 trace_26_272-2018423 trace_149_383-2018423 trace_209_96-2018423 trace_290_239-2018423