模板匹配是一种用于在图像中定位和识别对象的技术。它的基本思想是:
-
提取图像中的一个子图像作为"模板"(template)。这个子图像通常包含我们感兴趣的目标对象。
-
在整个原始图像上,逐点比较模板和原始图像的相似度。相似度通常用归一化的交叉相关(Normalized Cross Correlation, NCC)来度量。
-
当相似度达到最大时,原始图像中的该位置就是模板的匹配位置。也就是我们要找的目标对象的位置。
主要的步骤包括:
-
获取模板图像:先从原图像中裁剪包含目标的子图像作为模板图。
-
在原图像上滑动模板,计算每个位置的相似度:用模板图像在原图像上逐步滑动,每个位置计算模板图和原图的重叠区域的相似度。常用的相似度度量方法是归一化的交叉相关(NCC)。
-
寻找最佳匹配:相似度最大的位置即为最佳匹配位置,对应模板图像在原图像的位置。
-
设置相似度阈值:只有相似度大于某一阈值的匹配结果才是有效的。
模板匹配简单高效,应用广泛,但只适用于目标变形不大的情况。当目标发生旋转、缩放等变换时,效果会下降。这时可以考虑改进的模板匹配方法或其他更advanced的方法。
MATLAB代码如下:
clc;close all;clear all;warning off;%清除变量
rand('seed', 100);
randn('seed', 100);
format long g;
% im1=imread('1face.bmp');% 读入模板图像
% im2=imread('eye.bmp');%读入测试图像
im1=imread('S.jpg');
im2=imread('letters.jpg');
result=matchfun(im1,im2);
figure;
subplot(1,3,1);
imshow(im1);
title('模板');%显示模板
subplot(1,3,2);
imshow(im2);
title('测试图像');%显示测试图像
subplot(1,3,3);
imshow(result);
title('匹配结果');
function result=matchfun(image1,image2)
%*********************************************************
%如果是三维图像就转换为二维灰度图像
if size(image1,3)==3
image1=rgb2gray(image1);
end
if size(image2,3)==3
image2=rgb2gray(image2);
end
% 通过图片的尺寸判断哪个是测试图片哪个是模板
if size(image1)>size(image2)
Target=image1;
Template=image2;
else
Target=image2;
Template=image1;
end
% 取得两幅图片的尺寸
[r1,c1]=size(Target);
[r2,c2]=size(Template);
% 模板的均值
image22=Template-mean(mean(Template));%X-E(X)
%两幅图像的相关性
M=[];%相关系数 矩阵
for i=1:(r1-r2+1)%横向搜索
for j=1:(c1-c2+1)%纵向搜索
Nimage=Target(i:i+r2-1,j:j+c2-1); %区域的选取,r2,c2为选取的大小
Nimage=Nimage-mean(mean(Nimage)); %Y-E(Y)
corr=sum(sum(Nimage.*image22));%E(X)*E(Y)取和与Cov(X,Y)成正比
warning off
M(i,j)=corr/(sqrt(sum(sum(Nimage.^2)))*sqrt(sum(sum(image22.^2))));%X与Y均方差的积
end
end
% 在测试的图像中标注出目标的位置
result=plotbox(Target,Template,M);
function result=plotbox(Target,Template,M);
%**********判断目标的位置并标记************
[r1,c1]=size(Target);
[r2,c2]=size(Template);
[r,c]=max(M);%r每一列的最大值,c每列最大值所在的行数,都为一维矩阵
[r3,c3]=max(max(M));%r3 矩阵中的最大值,c3最大值所在的列数
%确定最大值点的坐标
i=c(c3);%行数
j=c3;%列数
result=Target;
%画上边的横线
for x=i:i+r2-1
for y=j%一个像素点的宽度
result(x,y)=255;%画线设置成白色
end
end
%画下边的横线
for x=i:i+r2-1
for y=j+c2-1
result(x,y)=255;
end
end
%画左边的竖线
for x=i
for y=j:j+c2-1
result(x,y)=255;
end
end
%画右边的竖线
for x=i+r2-1
for y=j:j+c2-1
result(x,y)=255;
end
end
程序结果如下: