快速零均值歸一化互相關函數算法及MATLAB代碼實現

零均值歸一化互相關函數相對於別的一些相關函數,精度雖然沒有多大提升,但是它具有較強的抗干擾性和魯棒性。所以,在數字圖像相關法(DIC的圖像匹配過程中,一般都是使用零均值歸一化互相關函數,下面是其公式:


           


在進行數字圖像相關匹配時,通常分爲兩部分,首先是進行整像素的定位,然後是亞像素的精確計算。在進行亞像素的精確求解時,需要以整像素的定位結果爲基礎,因此,一個準確的整像素匹配座標對於後續的計算來說至關重要。數字圖像相關方法發展至今,已有許多學者提出了多種整像素匹配方法,例如初期的逐點法,以及後期的爬山法、粒子羣法等智能算法。雖然逐點法相對於之後的一些智能算法在速度上要落後很多,但是由於它是一種全局搜索方法,因此在準確性上要大大優於其它的方法。本節主要介紹了一種快速 ZNCC 算法,不僅保證了傳統逐點算法的準確性,還大大提高了計算速度(摘抄自《基於雙目視覺的DIC測量技術研究--肖穎》第三章3.2整像素相關匹配算法)。快速ZNCC算法原文請查看我的上傳資源

下面是MATLAB代碼實現:

這是主腳本:

%% 快速零均值歸一化互相關函數
%結果爲1相關性最好,值越小相關性最差
%計算兩個大小相同的灰度矩陣的相關係數
%%
tic
clear;
clc;
[filename1,pathname1,~]=uigetfile({'*.jpg';'*.jpeg';'*.bmp'},'選擇一張圖片');
orignf=imread([pathname1 filename1]);    %讀取參考子區色度信息
f=rgb2gray(orignf);                    %將照片轉化爲灰度照片
f=double(f);
[r1,c1]=size(f);
if rem(r1,2)==0
    f=imresize(f,[r1-1,c1]);
elseif rem(c1,2)==0
    f=imresize(f,[r1,c1-1]);
end
[r1,c1]=size(f);
[filename2,pathname2,~]=uigetfile({'*.jpg';'*.jpeg';'*.bmp'},'選擇一張圖片');
orignG=imread([pathname2 filename2]);    %讀取目標圖像照片色度信息
G=rgb2gray(orignG);                    %讀取照片色度信息
G=double(G);
[r2,c2]=size(G);
%%
F=sum(sum(f))/numel(f);           %參考子區照片灰度值平均值
den1=0;                           %分母左部分
for i=1:r1
    for j=1:c1
        den1=den1+(f(i,j)-F)^2;
    end
end
den1=sqrt(den1);
Subf=0;
for i=1:r1
    for j=1:c1
        Subf=Subf+f(i,j);
    end
end
m=r1;
n=c1;
Xmin=(m-1)/2+2;       %子區中心可選範圍
Xmax=r2-(m-1)/2;
Ymin=(n-1)/2+2;
Ymax=c2-(n-1)/2;
Sg=SumTableg(G,r2,c2);   %累加和表
Sgg=SumTablegg(G,r2,c2);
COE=zeros(Xmax-Xmin+1,Ymax-Ymin+1);
num=0;
den2=0;
for x=Xmin:Xmax
    for y=Ymin:Ymax
        g=G(x-(m-1)/2:x+(m-1)/2,y-(n-1)/2:y+(n-1)/2);    %目標子區
        Sfg=SumTablefg(f,g,r1,c1);
        Meang=sum(sum(g))/numel(g);           %目標子區平均灰度值
        Subg=Sg(x+(m-1)/2,y+(n-1)/2)-Sg(x-(m-1)/2-1,y+(n-1)/2)...
            -Sg(x+(m-1)/2,y-(n-1)/2-1)+Sg(x-(m-1)/2-1,y-(n-1)/2-1);
        Subgg=Sgg(x+(m-1)/2,y+(n-1)/2)-Sgg(x-(m-1)/2-1,y+(n-1)/2)...
            -Sgg(x+(m-1)/2,y-(n-1)/2-1)+Sgg(x-(m-1)/2-1,y-(n-1)/2-1);
        Subfg=Sfg(end,end);
        num=Subfg-Meang*Subf-F*Subg+r1*c1*F*Meang;
        den2=Subgg-2*Meang*Subg+Meang*Meang*r1*c1;
        den2=sqrt(den2);
        C=num/(den1*den2);
        COE(x-Xmin+1,y-Ymin+1)=C;
    end
end
%% 
[M,~]=max(COE);
[~,J]=max(M);
y=Ymin+J;
[M,I]=max(COE(:,J));
x=Xmin+I;
fprintf('最大相關係數是:%.6f\n',M)
L=2;   %畫框寬度,單位像素
orignGCopy(:,:,1)=orignG(x-(m-1)/2+L:x+(m-1)/2-L,y-(n-1)/2+L:y+(n-1)/2-L,1);
orignGCopy(:,:,2)=orignG(x-(m-1)/2+L:x+(m-1)/2-L,y-(n-1)/2+L:y+(n-1)/2-L,2);
orignGCopy(:,:,3)=orignG(x-(m-1)/2+L:x+(m-1)/2-L,y-(n-1)/2+L:y+(n-1)/2-L,3);
%% 
orignG(x-(m-1)/2:x+(m-1)/2,y-(n-1)/2:y+(n-1)/2,1)=255;
orignG(x-(m-1)/2:x+(m-1)/2,y-(n-1)/2:y+(n-1)/2,2)=0;
orignG(x-(m-1)/2:x+(m-1)/2,y-(n-1)/2:y+(n-1)/2,3)=0;
orignG(x-(m-1)/2+L:x+(m-1)/2-L,y-(n-1)/2+L:y+(n-1)/2-L,1)=orignGCopy(:,:,1);
orignG(x-(m-1)/2+L:x+(m-1)/2-L,y-(n-1)/2+L:y+(n-1)/2-L,2)=orignGCopy(:,:,2);
orignG(x-(m-1)/2+L:x+(m-1)/2-L,y-(n-1)/2+L:y+(n-1)/2-L,3)=orignGCopy(:,:,3);

image(orignG)
toc

下面的這些都是主腳本所需函數:

function GraySum=SumTableg(P,m,n)
S=zeros(m,n);
for x=1:m
    for y=1:n
        if x==1
            for j=1:y
                S(x,y)=S(x,y)+P(x,j);
            end
        elseif y==1&&x~=1
            for i=1:x
                S(x,y)=S(x,y)+P(i,y);
            end
        else
            S(x,y)=P(x,y)+S(x-1,y)+S(x,y-1)-S(x-1,y-1);
        end
    end
end
GraySum=S;
end
function GraySum=SumTablegg(P,m,n)
S=zeros(m,n);
for x=1:m
    for y=1:n
        if x==1
            for j=1:y
                S(x,y)=S(x,y)+P(x,j).^2;
            end
        elseif y==1&&x~=1
            for i=1:x
                S(x,y)=S(x,y)+P(i,y).^2;
            end
        else
            S(x,y)=P(x,y).^2+S(x-1,y)+S(x,y-1)-S(x-1,y-1);
        end
    end
end
GraySum=S;
end
function GraySum=SumTablefg(F,G,m,n)
S=zeros(m,n);
for x=1:m
    for y=1:n
        if x==1
            for j=1:y
                S(x,y)=S(x,y)+F(x,j)*G(x,j);
            end
        elseif y==1&&x~=1
            for i=1:x
                S(x,y)=S(x,y)+F(i,y)*G(i,y);
            end
        else
            S(x,y)=F(x,y)*G(x,y)+S(x-1,y)+S(x,y-1)-S(x-1,y-1);
        end
    end
end
GraySum=S;
end

在運行程序時,選擇的第一張圖片是參考子區(像素少的),第二張是目標圖像(像素多的),千萬不要錯了!!!

下面是兩張圖片:

                                       圖一                                                 圖二

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章