1.模板匹配基本原理概述
当我们比较两幅图像的时候,首先面对的基本问题是:什么时候两幅图像才是一样或比较相似的,这两幅图像的相似程度如何衡量?当然,比较一般的方法是,当两幅图像的所有像素灰度值一样的时候,我们认为这样幅图是一样的。这种比较方法在某些特定的应用领域是可行的,比如在恒定光照环境和相机内部环境下,检测连续两帧图像的变化。简单的比较像素之间的差值在大多数应用场合下是不太合适的。噪声、量化误差、微小的光照变化、极小的平移或旋转在两幅图像像素简单差值的时候将产生较大的像素差值,但是人眼观察看来,两幅图像仍然是一样的。显然,人类知觉能够感应更为广泛的相似性内容,即使在单个像素差值较大的情况下,也能够利用诸如结构和图像内容来识别两幅图像的相似性。在结构或语义层面比较图像是一个比较困难的问题,同时也是一个比较有趣的研究领域。
在这我们介绍的是一种在像素层面相对简单的图像比较方法。即在一幅较大图像定位一幅给定的子图像-----模板图像,即通常所说的模板匹配。这种情况经常发生,比如在一个图像场景中定位一个特定的物体,或者是在图像序列中追踪最某些特定模式。模板匹配的基本原理很简单:在待搜寻的图像中,移动模板图像,在每一个位置测量待搜寻图像的子图像和模板图像的差值,当相似度达到最大时,记录其相应的位置。但实际情况却不是这么简单,如何选取合适的距离测量方法?当亮度或对比度改变时应该如何处理?匹配中总的距离差值为多少才可以被认为是相似度比较高?这些问题都需要根据实用情况加以考虑。
以上图像都“相同”吗?在原始图像(a)和其他五幅图像(b-f)中,简单的比较图像像素间的差值将会得到较大的距离值。
模板匹配的基本原理。以两幅图像的原点为参考点,参考图像R在待搜寻的图像I中平移(r,s)个单位,待搜寻图像的大小和模板图像的大小确定的最大的搜寻区域。
2.灰度图像中的模板匹配
灰度图像中的模板匹配,主要是找到模板图像R和搜寻图像I中的子图像相同或最相似的位置。以下式子表示模板在原始图像偏移(r,s)单位,
参考图像R分别在水平方法和竖直方向平移r和s个单位,那么模板匹配的问题可以概述为:
给定搜寻图像I和模板图像R。找到平移后的参考图像以及搜寻图像中所对应的子图像相似度最大的位置。
2.1图像匹配中的距离函数
模板匹配中最重要的是找到一种对灰度和对比度变化具有较好鲁棒性的相似度测量函数。
为了测量图像间的相似度程度,我们计算每一次平移(r,s)后的参考图像和搜寻图像中所对应的子图像的“距离”d(r,s)(如下图所示)。二维灰度图像中的测量函数有如下基本的几种:
二维图像中距离测量函数的表示
Sum ofabsolute differences:
Maximumdifference:
Sum ofsquared differences:
由于SSD函数的特性,在统计和最优化领域被经常用到。为了找到参考图像在搜寻图像中的最佳匹配位置,只要使得SSD函数取得最小值即可。即
上式中的B是参考图像中所有像素灰度值的平方和,是一个常量(独立于r,s)因此在计算其最小值的时候可以忽略。A(r,s)表示的是搜寻图像在(r,s)的子图像中所有像素灰度值的平方和,C(r,s)即称为搜寻图像和参考图像的线性互相关函数,通常可以表示为:
当R 和I超出边界时,其值为零,故上式亦可表示为:
如果我们假设A(r,s)在搜寻图像中是一个常量,那么SSD中计算其最佳匹配位置的时候,其值是可以忽略的,且当C(r,s)取得最大值的时候,参考图像和搜寻图像中的子图像最相似。这种情况下,SSD的最小值可以通过计算C(r,s)的最大值获得。
2.2归一化的互相关
实际应用当中,上述假定A(r,s)为一常量并不总是成立。因此,上述的互相关的结果将随着搜寻图像中像素灰度值的改变而产生较大变化。归一化的互相关把参考图像和当前的子图像的能量考虑进去:
当参考图像和搜寻图像子图像灰度值都是正数的时候,Cn(r,s)的值总是为[0,1]范围内,与图像其他像素灰度值无关。当Cn(r,s)等于1时,表明在平移位置(r,s),参考图像和子图像达到最大相似度;相反,当Cn(r,s)等于0时,表明在平移位置(r,s),参考图像和子图像完全不匹配。当子图像中的所有灰度值改变时,归一化的互相关Cn(r,s)也会极大的改变。
2.2相关系数
为了解决上述问题,我们引入子图像和模板图像中的灰度平均值。上述归一化函数可以改写为:
子图像和参考图像平均值分别定义为:
其中,K表示参考图像中像素的数量。在统计学中,上述表达式被称为相关系数。然而,与统计学中作为全局测量方法不同的是,CL(r,s)被定义是一个局部的测量函数。CL(r,s)的值域范围为[-1,1]。当CL(r,s)等于1时,表明在平移位置(r,s),参考图像和子图像达到最大相似度;相反,当CL(r,s)等于0时,表明在平移位置(r,s),参考图像和子图像完全不匹配。表达式:
表示的是K倍模板图像R中像素灰度值方差,这是一个常量,只需要计算一次即可。由于方差存在如下关系:(具体可参考http://imagej.net/Integral_Image_Filters)
具体推到如下所示:
因此,可以SR改写为
带入到CL(r,s),可得:
由此,可得到一个高效的计算相关系数的方法。
function varargout = FacialExpressionRecognitiontool(varargin)
% FACIALEXPRESSIONRECOGNITIONTOOL MATLAB code for FacialExpressionRecognitiontool.fig
% FACIALEXPRESSIONRECOGNITIONTOOL, by itself, creates a new FACIALEXPRESSIONRECOGNITIONTOOL or raises the existing
% singleton*.
%
% H = FACIALEXPRESSIONRECOGNITIONTOOL returns the handle to a new FACIALEXPRESSIONRECOGNITIONTOOL or the handle to
% the existing singleton*.
%
% FACIALEXPRESSIONRECOGNITIONTOOL('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in FACIALEXPRESSIONRECOGNITIONTOOL.M with the given input arguments.
%
% FACIALEXPRESSIONRECOGNITIONTOOL('Property','Value',...) creates a new FACIALEXPRESSIONRECOGNITIONTOOL or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before FacialExpressionRecognitiontool_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to FacialExpressionRecognitiontool_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help FacialExpressionRecognitiontool
% Last Modified by GUIDE v2.5 23-Oct-2014 12:52:25
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @FacialExpressionRecognitiontool_OpeningFcn, ...
'gui_OutputFcn', @FacialExpressionRecognitiontool_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before FacialExpressionRecognitiontool is made visible.
function FacialExpressionRecognitiontool_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to FacialExpressionRecognitiontool (see VARARGIN)
% Choose default command line output for FacialExpressionRecognitiontool
set(handles.togglebutton1,'visible','off')
set(handles.togglebutton2,'visible','off');
set(handles.text2,'visible','off');
set(handles.edit2,'visible','off');
set(handles.text3,'visible','off');
axes(handles.axes2)
cla
axes(handles.axes1)
cla
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes FacialExpressionRecognitiontool wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = FacialExpressionRecognitiontool_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global A m1 n1 No_Files_In_Class_Folder Class_Count Training_Set_Folder
title('测试图片','Color','black','FontSize',15);
drawnow;
% set(handles.edit2,'string',test_image_path);
% set(handles.text5,'Visible','Off');
Test_File = [Test_File_Path Test_File];
test = imread(Test_File);
if length(size(test))==3
Test_Image = rgb2gray(test);
else
Test_Image = test;
end
Test_Image_Down_Sampled = double(imresize(Test_Image,[m1 n1]));
y = Test_Image_Down_Sampled(:);
n = size(A,2);
% minimize norm(x1,1)
% subject to
% A*x1 == y;
% cvx_end
% figure,plot(x1);
f=ones(2*n,1);
Aeq=[A -A];
lb=zeros(2*n,1);
x1 = linprog(f,[],[],Aeq,y,lb,[],[],[]);
x1 = x1(1:n)-x1(n+1:2*n);
figure
bar(x1/1000,0.2) %参数中y表示数据,0.2表示柱状图中柱子的宽度
legend('稀疏系数','WestOutside');
nn = No_Files_In_Class_Folder;
nn = cumsum(nn);
tmp_var = 0;
k1 = Class_Count-1;
for i = 1:k1
delta_xi = zeros(length(x1),1);
if i == 1
delta_xi(1:nn(i)) = x1(1:nn(i));
else
tmp_var = tmp_var + nn(i-1);
begs = nn(i-1)+1;
ends = nn(i);
delta_xi(begs:ends) = x1(begs:ends);
end
tmp(i) = norm(y-A*delta_xi,2);
tmp1(i) = norm(delta_xi,1)/norm(x1,1);
end
Sparse_Conc_Index = (k1*max(tmp1)-1)/(k1-1);
clss = find(tmp==min(tmp));
cccc = dir([Training_Set_Folder]);
Which_Folder = dir([Training_Set_Folder,cccc(clss+2).name,'\']);
Which_Image = randsample(3:length(Which_Folder),1);
Image_Path = [Training_Set_Folder,cccc(clss+2).name,'\',Which_Folder(Which_Image).name];
Class_Image = (Image_Path);
axes(handles.axes2);
imshow(Class_Image)
title('训练图片','Color','red','FontSize',15)
set(handles.edit1,'visible','on');
set(handles.edit1,'string',[cccc(clss+2).name]);
set(handles.edit5,'visible','off');
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global A m1 n1 No_Files_In_Class_Folder Class_Count Training_Set_Folder
set(handles.togglebutton1,'visible','off')
set(handles.togglebutton2,'visible','off');
set(handles.text2,'visible','off');
set(handles.edit2,'visible','off');
set(handles.text3,'visible','off');
set(handles.edit5,'visible','on');
set(handles.edit1,'visible','on');
FullPath=uigetdir('');
IsTrue=0;
TotImg=0;
TestFiles=dir(FullPath);
for k=1:length(TestFiles)
if ~strcmp(TestFiles(k,1).name(1),'.')
Imgfiles=dir([FullPath '\' TestFiles(k).name]);
for m=1:length(Imgfiles)
if ~strcmp(Imgfiles(m,1).name(1),'.')
axes(handles.axes1)
Test_File = [FullPath '\' TestFiles(k,1).name '\' Imgfiles(m,1).name];
set(handles.edit1,'string',[TestFiles(k,1).name '\' Imgfiles(m,1).name]);
imshow(Test_File)
drawnow;
test = imread(Test_File);
if length(size(test))==3
Test_Image = rgb2gray(test);
else
Test_Image = test;
end
Test_Image_Down_Sampled = double(imresize(Test_Image,[m1 n1]));
y = Test_Image_Down_Sampled(:);
n = size(A,2);
% cvx_quiet true
% cvx_begin
% variable x1(n)
% minimize norm(x1,1)
% subject to
% A*x1 == y;
% cvx_end
% figure,plot(x1);
f=ones(2*n,1);
Aeq=[A -A];
lb=zeros(2*n,1);
x1 = linprog(f,[],[],Aeq,y,lb,[],[],[]);
x1 = x1(1:n)-x1(n+1:2*n);
nn = No_Files_In_Class_Folder;
nn = cumsum(nn);
tmp_var = 0;
k1 = Class_Count-1;
for i = 1:k1
delta_xi = zeros(length(x1),1);
if i == 1
delta_xi(1:nn(i)) = x1(1:nn(i));
else
tmp_var = tmp_var + nn(i-1);
begs = nn(i-1)+1;
ends = nn(i);
delta_xi(begs:ends) = x1(begs:ends);
end
tmp(i) = norm(y-A*delta_xi,2);
tmp1(i) = norm(delta_xi,1)/norm(x1,1);
end
TotImg=TotImg+1;
Sparse_Conc_Index(TotImg) = (k1*max(tmp1)-1)/(k1-1);
clss = find(tmp==min(tmp));
% figure,plot(tmp)
ssttrr = sprintf('The Test Image Corresponds to Class: %d',clss);
cccc = dir([Training_Folder]);
Which_Folder = dir([Training_Folder,cccc(clss+2).name,'\']);
Which_Image = randsample(3:length(Which_Folder),1);
Image_Path = [Training_Folder,cccc(clss+2).name,'\',Which_Folder(Which_Image).name];
Class_Image = (Image_Path);
set(handles.edit5,'string',[cccc(clss+2).name]);
axes(handles.axes2);
imshow(Class_Image)
% title('Detected Image','Color','black','FontSize',25)
set(handles.togglebutton1,'visible','on')
set(handles.togglebutton2,'visible','on');
set(handles.text2,'visible','on');
while 1
pause(eps)
if get(handles.togglebutton1,'value')==1
IsTrue=IsTrue+1;
set(handles.togglebutton1,'value',0)
break;
elseif get(handles.togglebutton2,'value')==1
set(handles.togglebutton2,'value',0)
break;
end
end
set(handles.togglebutton1,'visible','off')
set(handles.togglebutton2,'visible','off');
set(handles.text2,'visible','off');
axes(handles.axes2)
% cla
end
end
end
end
eta = (IsTrue/TotImg)*100;
set(handles.edit2,'visible','on');
set(handles.text3,'visible','on');
set(handles.edit2,'String',[num2str(eta) '%']);
drawnow;
set(handles.togglebutton1,'visible','off')
set(handles.togglebutton2,'visible','off');
% --- Executes on button press in togglebutton1.
function togglebutton1_Callback(hObject, eventdata, handles)
% hObject handle to togglebutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.togglebutton1,'value',1)
% Hint: get(hObject,'Value') returns toggle state of togglebutton1
% --- Executes on button press in togglebutton2.
function togglebutton2_Callback(hObject, eventdata, handles)
% hObject handle to togglebutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.togglebutton2,'value',1);
% Hint: get(hObject,'Value') returns toggle state of togglebutton2
% --- Executes during object creation, after setting all properties.
function text4_CreateFcn(hObject, eventdata, handles)
% hObject handle to text4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
function edit2_Callback(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as text
% str2double(get(hObject,'String')) returns contents of edit2 as a double
% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function edit5_Callback(hObject, eventdata, handles)
% hObject handle to edit5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit5 as text
% str2double(get(hObject,'String')) returns contents of edit5 as a double
% --- Executes during object creation, after setting all properties.
function edit5_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes during object creation, after setting all properties.
function text2_CreateFcn(hObject, eventdata, handles)
% hObject handle to text2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% --- Executes during object creation, after setting all properties.
function text3_CreateFcn(hObject, eventdata, handles)
% hObject handle to text3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% --- Executes during object creation, after setting all properties.
function axes2_CreateFcn(hObject, eventdata, handles)
% hObject handle to axes2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate axes2
% --- Executes during object creation, after setting all properties.
function axes1_CreateFcn(hObject, eventdata, handles)
% hObject handle to axes1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate axes1