基于灰度的匹配算法又称为基于模板的匹配算法,子图与模板图对应位置上灰度值计算得出一个值,这个值可以是对应像素相减绝对值的加和(即SAD算法),也可以将计算出的和除以模板像素个数,即(MAD算法),其它基于灰度的图像匹配算法均基于此思想,只不过所计算的值不同。以下将逐个进行介绍。
SAD算法
参考图 模板图SAD算法即模板与参考图对应像素相减的绝对值求和,然后在依次滑动模板遍历每个位置,得到(P-M)行,(Q-N)列的矩阵,其中值最小的位置即说明模板与参考图相似度最高。SAD相似性公式如下,(由于算法中直接用矩阵计算,与公式表达方式上不同,但实质相同)
可根据下图结合代码进行实现
SAD/MAD算法
%%
%绝对误差和算法(SAD)
%%
clear all;
close all;
%%读取参考图
src=imread('Lanny.png');%导入参考图
[a b d]=size(src);%获取图像长宽以及通道数
if d==3
src=rgb2gray(src);%判断是否灰度图,若不是则转为灰度图
end
%%读取模板图,原理同读取参考图
mask=imread('mark.png');
[m n d]=size(mask);
if d==3
mask=rgb2gray(mask);
end
%%
N=n;%模板尺寸,此处为矩形(高,宽)=(M,N)
M=m;
P=a;%代搜索图像尺寸,同上
Q=b;
%%进行匹配
dst=zeros(P-M,Q-N);%创建矩阵,存放模板计算出的结果
S=M*N;
for i=1:P-M %子图选取,每次滑动一个像素
for j=1:Q-N
temp=src(i:i+M-1,j:j+N-1);%当前子图
dst(i,j)=sum(sum(abs(temp-mask)))/S;%%此处除以S即为MAD,不除即为SAD
end
end
abs_min=min(min(dst));%%寻找最小值
[x,y]=find(dst==abs_min);
figure;
imshow(mask);title('模板');
figure;
imshow(src);
hold on;
rectangle('position',[y,x,N-1,M-1],'edgecolor','r');%在参考图上框选匹配出的结果
hold off;title('搜索图');
Ncc匹配算法如下
%%
%绝对误差和算法(SAD)
%%
clear all;
close all;
%%读取参考图
src=imread('Lanny.png');%导入参考图
[a b d]=size(src);%获取图像长宽以及通道数
if d==3
src=rgb2gray(src);%判断是否灰度图,若不是则转为灰度图
end
%%读取模板图,原理同读取参考图
mask=imread('mark.png');
[m n d]=size(mask);
if d==3
mask=rgb2gray(mask);
end
mask=im2double(mask);
%%
N=n;%模板尺寸,此处为矩形(高,宽)=(M,N)
M=m;
P=a;%代搜索图像尺寸,同上
Q=b;
%%进行匹配
dst=zeros(P-M,Q-N);%创建矩阵,存放模板计算出的结果
S=M*N;
for i=1:P-M %子图选取,每次滑动一个像素
for j=1:Q-N
temp=src(i:i+M-1,j:j+N-1);%当前子图
temp=im2double(temp); %注意要将int转为double型
%dst(i,j)=sum(sum((abs(temp-mask).^2)));%%此处除以S即为MAD,不除即为SAD
temp_m=mean(mean(temp));
mask_m=mean(mean(mask));
a=((sum(sum((temp-temp_m).*(mask-mask_m)))));
b=(sqrt(sum(sum(((temp-temp_m).^2))))* sqrt(sum(sum(((mask-mask_m).^2)))));
dst(i,j)=a/b;
end
end
abs_max=max(max(dst));%%寻找最小值
[x,y]=find(dst==abs_max);
figure;
imshow(mask);title('模板');
figure;
imshow(src);
hold on;
rectangle('position',[y,x,N-1,M-1],'edgecolor','r');%在参考图上框选匹配出的结果
hold off;title('搜索图');
序贯相似性检测算法(SSDA)代码如下
%%
%绝对误差和算法(SAD)
%%
clear all;
close all;
%%读取参考图
src=imread('Lanny.png');%导入参考图
[a b d]=size(src);%获取图像长宽以及通道数
if d==3
src=rgb2gray(src);%判断是否灰度图,若不是则转为灰度图
end
%%读取模板图,原理同读取参考图
mask=imread('mark.png');
[m n d]=size(mask);
if d==3
mask=rgb2gray(mask);
end
mask=im2double(mask);
%%
N=n;%模板尺寸,此处为矩形(高,宽)=(M,N)
M=m;
P=a;%代搜索图像尺寸,同上
Q=b;
%%进行匹配
dst=zeros(P-M,Q-N);%创建矩阵,存放模板计算出的结果
for i=1:P-M %子图选取,每次滑动一个像素
for j=1:Q-N
temp=src(i:i+M-1,j:j+N-1);%当前子图
temp=im2double(temp); %注意要将int转为double型
sum_pipei=0;
for x=1:M
for y=1:N
sum_pipei=sum_pipei+abs(temp(x,y)-mask(x,y));
if sum_pipei>15
break;
end
dst(i,j)=dst(i,j)+1;
end
if sum_pipei>15
break;
end
end
end
end
abs_max=max(max(dst));%%寻找最小值
[x,y]=find(dst==abs_max);
figure;
imshow(mask);title('模板');
figure;
imshow(src);
hold on;
rectangle('position',[y,x,N-1,M-1],'edgecolor','r');%在参考图上框选匹配出的结果
hold off;title('搜索图');
hadamard变换算法(SATD)
路线图如下
matlab代码如下
clc;
clear all;
src=imread('Lanny.png');
mark=imread('mark.png');
src_l=im2double(src);
src_l=rgb2gray(src_l);
mark_l=im2double(mark);
mark_l=rgb2gray(mark_l);
[a b d]=size(src_l);%获取图像长宽以及通道数
[m n d]=size(mark_l);
H1=hadamard(m);%产生512X512的Hadamard矩阵
H2=hadamard(n);
% mark_l=H1*mark_l*H2;
% mark_l=mark_l/a;
N=n;%模板尺寸,此处为矩形(高,宽)=(M,N)
M=m;
P=a;%代搜索图像尺寸,同上
Q=b;
dst=zeros(P-M,Q-N);%创建矩阵,存放模板计算出的结果
for i=1:P-M %子图选取,每次滑动一个像素
for j=1:Q-N
temp=src_l(i:i+M-1,j:j+N-1);%当前子图
pic=abs(temp-mark_l);
pic=H1*pic*H2/a;
dst(i,j)=sum(sum(abs(pic)));
end
end
abs_max=min(min(dst));%%寻找最小值
[x,y]=find(dst==abs_max);
figure;
imshow(mark);title('模板');
figure;
imshow(src);
hold on;
rectangle('position',[y,x,N-1,M-1],'edgecolor','r');%在参考图上框选匹配出的结果
hold off;title('搜索图');
互信息、归一化互信息(Normalization Mutual Information,NMI)、熵相关系数(Entropy Corrleation Coefficient,ECC)算法,该算法本质上是基于图像直方图的匹配算法
对于一幅图像来说,其熵的计算表达式如下:
hi表示图像Y中灰度值为i的像素点总数,N表示图像Y的灰度级数。显然Pi表示灰度i出现的概率,于是很自然的就会想到用直方图来计算。(对于单幅图像MATLAB中可由entropy()函数求得)
两幅图像的联合熵如下
联合熵类似于图像的二维熵,可以将灰度值与坐标关系联系起来
互信息
在图像配准中,两幅图的互信息是通过它们的熵以及联合熵,来反映它们之间信息的相互包含成都程度(02-21-2017更正)。对于图像R、F来说,其互信息表示为:
当两幅图像相似度越高或重合部分越大时,其想关性也越大,联合熵越小,也即互信息越大。
归一化互信息(Normalization Mutual Information,NMI)
熵相关系数
代码如下
clc;
clear all;
%%读取参考图
%//图像互信息配准
%----------------读取原图像------------------------
src=imread('Lanny.png');%导入参考图
[a b d]=size(src);%获取图像长宽以及通道数
if d==3
src=rgb2gray(src);%判断是否灰度图,若不是则转为灰度图
end
%----------------读取模板图------------------------
mask=imread('mark.png');
[m n d]=size(mask);
if d==3
mask=rgb2gray(mask);
end
%----------------计算模板熵------------------------
ET=entropy(mask);%//模板熵
%----------------计算子图熵、联合熵----------------
MI=zeros(a-m,b-n);%//互信息
NMI=zeros(a-m,b-n);%//归一化互信息
ECC=zeros(a-m,b-n);%//熵相关系数
for i=1:a-m
for j=1:b-n
temp=src(i:i+m-1,j:j+n-1);%//子图
ES=entropy(temp);%//模子图熵
histq=zeros(256,256);%//联合直方图,清空
%//联合直方图
for s=1:m
for t=1:n
x=src(s,t)+1;y=mask(s,t)+1;%//灰度<—>坐标
histq(x,y)=histq(x,y)+1;
end
end
p=histq./sum(sum(histq));%//联合概率密度
EST=-sum(sum(p.*log(p+eps)));%//联合熵(越小说明相似度越高)
MI(i,j)=ES+ET-EST;%//MI互信息越大,说明相互包含的信息多,即越匹配
NMI(i,j)=(ES+ET)/EST;%//NMI,越大越匹配
ECC(i,j)=2*MI(i,j)/(ES+ET);%//ECC,越大越匹配
end
end
%----------------输出----------------
mi_max=max(max(MI));
nmi_max=max(max(NMI));
ncc_max=max(max(ECC));
[xt1,yt1]=find(MI==mi_max);
[xt2,yt2]=find(NMI==nmi_max);
[xt3,yt3]=find(ECC==ncc_max);
% dst1=img(xt1:xt1+dx-1,yt1:yt1+dx-1);
% dst2=img(xt2:xt2+dx-1,yt2:yt2+dx-1);
% dst3=img(xt3:xt3+dx-1,yt3:yt3+dx-1);
figure;imshow(mask);title('模板');
figure;imshow(src);hold on;rectangle('position',[yt1,xt1,n-1,m-1],'edgecolor','r');title('MI配准图');hold off;
figure;imshow(src);hold on;rectangle('position',[yt2,xt2,n-1,m-1],'edgecolor','r');title('NMI配准图');hold off;
figure;imshow(src);hold on;rectangle('position',[yt3,xt3,n-1,m-1],'edgecolor','r');title('NCC配准图');hold off;
%//over
至此,基于灰度的匹配暂时告一段落