天天看點

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

1.模闆比對基本原理概述

      當我們比較兩幅圖像的時候,首先面對的基本問題是:什麼時候兩幅圖像才是一樣或比較相似的,這兩幅圖像的相似程度如何衡量?當然,比較一般的方法是,當兩幅圖像的所有像素灰階值一樣的時候,我們認為這樣幅圖是一樣的。這種比較方法在某些特定的應用領域是可行的,比如在恒定光照環境和相機内部環境下,檢測連續兩幀圖像的變化。簡單的比較像素之間的內插補點在大多數應用場合下是不太合适的。噪聲、量化誤差、微小的光照變化、極小的平移或旋轉在兩幅圖像像素簡單內插補點的時候将産生較大的像素內插補點,但是人眼觀察看來,兩幅圖像仍然是一樣的。顯然,人類知覺能夠感應更為廣泛的相似性内容,即使在單個像素內插補點較大的情況下,也能夠利用諸如結構和圖像内容來識别兩幅圖像的相似性。在結構或語義層面比較圖像是一個比較困難的問題,同時也是一個比較有趣的研究領域。

      在這我們介紹的是一種在像素層面相對簡單的圖像比較方法。即在一幅較大圖像定位一幅給定的子圖像-----模闆圖像,即通常所說的模闆比對。這種情況經常發生,比如在一個圖像場景中定位一個特定的物體,或者是在圖像序列中追蹤最某些特定模式。模闆比對的基本原理很簡單:在待搜尋的圖像中,移動模闆圖像,在每一個位置測量待搜尋圖像的子圖像和模闆圖像的內插補點,當相似度達到最大時,記錄其相應的位置。但實際情況卻不是這麼簡單,如何選取合适的距離測量方法?當亮度或對比度改變時應該如何處理?比對中總的距離內插補點為多少才可以被認為是相似度比較高?這些問題都需要根據實用情況加以考慮。

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI
【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

     以上圖像都“相同”嗎?在原始圖像(a)和其他五幅圖像(b-f)中,簡單的比較圖像像素間的內插補點将會得到較大的距離值。

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

       模闆比對的基本原理。以兩幅圖像的原點為參考點,參考圖像R在待搜尋的圖像I中平移(r,s)個機關,待搜尋圖像的大小和模闆圖像的大小确定的最大的搜尋區域。

2.灰階圖像中的模闆比對

     灰階圖像中的模闆比對,主要是找到模闆圖像R和搜尋圖像I中的子圖像相同或最相似的位置。以下式子表示模闆在原始圖像偏移(r,s)機關,

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

    參考圖像R分别在水準方法和豎直方向平移r和s個機關,那麼模闆比對的問題可以概述為:

   給定搜尋圖像I和模闆圖像R。找到平移後的參考圖像以及搜尋圖像中所對應的子圖像相似度最大的位置。

2.1圖像比對中的距離函數

   模闆比對中最重要的是找到一種對灰階和對比度變化具有較好魯棒性的相似度測量函數。

    為了測量圖像間的相似度程度,我們計算每一次平移(r,s)後的參考圖像和搜尋圖像中所對應的子圖像的“距離”d(r,s)(如下圖所示)。二維灰階圖像中的測量函數有如下基本的幾種:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

二維圖像中距離測量函數的表示

Sum ofabsolute differences:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

Maximumdifference:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

Sum ofsquared differences:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

由于SSD函數的特性,在統計和最優化領域被經常用到。為了找到參考圖像在搜尋圖像中的最佳比對位置,隻要使得SSD函數取得最小值即可。即    

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI
【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

         上式中的B是參考圖像中所有像素灰階值的平方和,是一個常量(獨立于r,s)是以在計算其最小值的時候可以忽略。A(r,s)表示的是搜尋圖像在(r,s)的子圖像中所有像素灰階值的平方和,C(r,s)即稱為搜尋圖像和參考圖像的線性互相關函數,通常可以表示為:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

     當R 和I超出邊界時,其值為零,故上式亦可表示為:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

      如果我們假設A(r,s)在搜尋圖像中是一個常量,那麼SSD中計算其最佳比對位置的時候,其值是可以忽略的,且當C(r,s)取得最大值的時候,參考圖像和搜尋圖像中的子圖像最相似。這種情況下,SSD的最小值可以通過計算C(r,s)的最大值獲得。

2.2歸一化的互相關

    實際應用當中,上述假定A(r,s)為一常量并不總是成立。是以,上述的互相關的結果将随着搜尋圖像中像素灰階值的改變而産生較大變化。歸一化的互相關把參考圖像和目前的子圖像的能量考慮進去:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

     當參考圖像和搜尋圖像子圖像灰階值都是正數的時候,Cn(r,s)的值總是為[0,1]範圍内,與圖像其他像素灰階值無關。當Cn(r,s)等于1時,表明在平移位置(r,s),參考圖像和子圖像達到最大相似度;相反,當Cn(r,s)等于0時,表明在平移位置(r,s),參考圖像和子圖像完全不比對。當子圖像中的所有灰階值改變時,歸一化的互相關Cn(r,s)也會極大的改變。

2.2相關系數

    為了解決上述問題,我們引入子圖像和模闆圖像中的灰階平均值。上述歸一化函數可以改寫為:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

   子圖像和參考圖像平均值分别定義為:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

    其中,K表示參考圖像中像素的數量。在統計學中,上述表達式被稱為相關系數。然而,與統計學中作為全局測量方法不同的是,CL(r,s)被定義是一個局部的測量函數。CL(r,s)的值域範圍為[-1,1]。當CL(r,s)等于1時,表明在平移位置(r,s),參考圖像和子圖像達到最大相似度;相反,當CL(r,s)等于0時,表明在平移位置(r,s),參考圖像和子圖像完全不比對。表達式:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

表示的是K倍模闆圖像R中像素灰階值方差,這是一個常量,隻需要計算一次即可。由于方差存在如下關系:(具體可參考http://imagej.net/Integral_Image_Filters)

        具體推到如下所示:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI
【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

     是以,可以SR改寫為

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI

  帶入到CL(r,s),可得:

【圖像識别】基于模闆比對之人臉表情識别matlab源碼含GUI
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           

繼續閱讀