【人脸表情识别】基于matlab GUI LBP+SVM脸部动态特征人脸表情识别【含Matlab源码 1369期】

·  阅读 1045

一、 LBP+SVM简介

人的脸部是非常值得关注的外部特征。人与人交流不需要接触对方就可以识别对象的一些心里活动,丰富多样的表情能够在很多情况下代替语言表达自己的内心情感。人与人不但可以通过表情来表达情绪,还能分辨出交流者的心理和态度。据Mehrabian的论述,人们在交流的时候肢体语言的方式占据最大比例。视频表情实时识别是一个很有应用价值的研究课题。

人面部表情的复杂性与细腻性使计算复杂度增加,计算量大的算法无法应用到实时视频处理中,所以选用何种算法提取何种特征以增强时效性成为研究难点。针对这一问题,国内外学者进行了研究。如基于Gabor小波变换和LBP(Local Binary Pattern)特征的表情识别方法,这些算法结构简单易实现,但识别率有待提高。文献提出结合时域信息的Gabor运动能量滤波器结合SVM实现表情分类,其效果优于Gabor滤波。针对人脸表情集中于眼睛、眉毛、嘴巴等区域的特点,学者提出了多种区域特征级联表情识别方法。将不同区域的细节特征按照一定的规则形成一个特征向量,并将数据降维后输入分类器进行识别,如文献将Gabor变换后的数据利用径向网络联合编码进行分类;文献通过LBP统计表情局部纹理特征并利用信息熵决策各区域的级联加权值。上述多种区域特征级联表情识别方法充分描述了人脸的表情特征,但是表示数据维度较高会影响识别的实时性。

近年来,级联形状回归模型在特征点检索方向上有了突破性进展,此回归模型从历史经验中获得关于人脸表观至人脸形状的映射方法,建立从表象至形态的映射方法。这类方式不用复杂的人脸形状及其表观建模,效率高,实现也方便,效果好。另外,深度学习方向的人脸特征点定位算法也有很好的效果。深度学习与形状回归框架相结合可更好地提升定位模型的准确性,是目前特征定位的主要方式之一。

迄今为止,虽然人脸表情自动识别技术在各种应用推动下发展很快,但鲁棒的自动人脸表情识别系统仍尚未建立。根据国内外学者对表情识别的研究,以上几种算法都有其各自的局限性,同时由于信息量过大,使得识别及分类算法的效率受到严重影响。如何提高算法的效率成为了分类识别算法重要的研究方面。

本文通过LBP算子检测人脸,利用多级级联回归树模型对人脸68个关键点进行训练,提取脸部表情的几何特征,并依据此特征结合SVM来判别人脸表情,进而完成7种表情的分类。

1 特征提取算法 表情识别一般讲的是从机器通过人脸的照片判别人物当时的情绪。从结构上理解表情即眉毛、鼻子、嘴巴和脸的不同组合,最简单的方式便是对这些几何位置进行分类来判别表情。本文提出采用LBP(局部二值模式)特征结合SVM(支持向量机)进行决策表情分类的方法,基本流程如图1所示。 在这里插入图片描述 图1 识别过程 人脸表情基本识别思路如下: 1)在图中找到人脸,这是最基本的要求。否则就无法获得五官的信息以提取表情特征; 2)找到人的面部以后,分析其几何与纹理特征来表示不同的表情; 3)选取分类方法来判别这些特征。

脸部情绪特征的提取一般有下面的方式:整体模版匹配和基于几何纹理特征的匹配。整体模板匹配中,模板一般用像素点或是向量。在几何特征的匹配中,在图中探测到主要的特征点,经由特征点的距离与主要部分相对尺寸得到特征向量。基于特征的方式比基于模板的方式计算量大,但对面部位置、尺度、头部方向、大小都不敏感。

1.1 人脸检测 局部二值模式(Local Binary Pattern,LBP)特征不会因为旋转或者光照变化而发生明显变化,并且LBP特征的算法比较容易计算,处理视频人脸表情识别能够更有效,实时性更好。局部是指图像上某个像素点的纹理特质,很多情况下是指这个点和周围像素点的关系;二值模式指用中心像素的二值化作为阈值。

最简单的LBP模式,将一幅图像以像素为单位分成若干3×3的区域。把周围8个像素的值与中心像素进行比对,若是不小于中心像素的值则被设置为1,不然的话为0。这样,3×3范围内的8个像素点经过与中心像素比较可产生8位二进制数00010011(将该二进制转换为十进制数即LBP码,共256种),即得到该窗口中心像素点的LBP值,这个值即可反映该区域的纹理信息。计算过程如图2所示。 在这里插入图片描述 图2 LBP算子计算过程 LBP算子值因光照而产生的变化很小,因为在不同光照下,不改变周围像素与中心像素的关系,即一定程度下均匀变化的光不影响LBP算子值。因此在一定程度上,该算法可以解决因光照带来的影响。同时LBP算法计算简单也有助于本文实时分析图像。如图3所示,不同光照下的LBP特征变化很小,可以解决一些因光照带来的影响。 在这里插入图片描述 图3 不同光照下的LBP特征 计算一整幅包含背景的人脸图像的LBP特征和人脸LBP特征进行比对是无法定位人脸的。LBP特征即可反应某处的纹理信息,进行人脸检测的思想是根据比较人脸图像与目标图像的LBP特征的相似性来确定该图像是否是人脸,但是该过程只是进行了人脸识别,也就是判断一幅图像是不是人脸,而非一副图像是否包含人脸,如何在一整幅图象中找到人脸才是关键。既然已经可以识别人脸,那么在输入图像中截取一部分分别进行LBP特征的提取与判定,可以判定图像中截取的位置是否为人脸,这样一直循环遍历整幅图像,便可以定位到人脸的位置。

本文采用设定的窗口在图像上滑动多尺度扫描整个图像,图4为人脸检测过程,通过分类器去判别是否是人脸。首先检测窗口与将要进行检测的对象进行对齐,然后移动窗口进行下一次比较,直到这副图像被窗口遍历,最后进行缩放原始进行多尺度检测,图5为多级级联分类进行定位人脸的过程。通过计算窗口覆盖下的图像特征,与目标特征进行匹配来确定这部分图像的内容。 在这里插入图片描述 图4 人脸检测过程 其中,计算两张图片LBP特征向量的相似度实现人脸识别,相似度公式为 在这里插入图片描述 该式即是卡方检验,可以检测类别的相关性。式中H1、H2分别为两幅图像的LBP直方图(Histogram)。d越小,表示差异越低,两幅图像越接近,越相似;相同则d为0。

1.2 训练关键点模型 人脸关键点检测(Facial Landmark Detection)是根据输入的人脸图像,自动定位出面部关键特征点,如眼睛、鼻尖、嘴角、眉毛以及人脸各部件轮廓点等。根据这些特征点的关系来判断目前的情绪状态。

因为有光照、姿态、遮挡等问题的负效应,人脸关键点检测不容易实现。本文首先用LBP特征定位人脸,并进行人脸目标跟踪,然后进行人脸68个关键点检测。本文利用几何特征进行表情检测,使用基于Ensemble of Regression Tress(ERT)算法级联回归,即基于梯度提高学习的回归树方法。该方式检测速度快,效果也不错。同时对于不完整的人脸依旧能够进行检测。

当获得一张图片后,算法会产生一个初始形状(initial shape)即先预估一个大致的特征点位置,然后采用Gradient Boosting方式减小初始形状和标注位置(ground truth,真实特征点位置)的偏差平方和(损失函数)。用最小二乘法使偏差最小化,获取每一级的级联回归因子。式(2)描述了偏差平方和,式中yi为预测值,ti为标注值。 在这里插入图片描述 Gradient Boosting算法是在迭代时选择梯度下降的方向来保障结果最好。损失函数用来表示模型的“靠谱”水平,如果模型未过拟合,损失函数变大,模型的错误率增高,如果让算法能够使损失函数一直降低,即表明算法模型在不断地改进,而最佳的方法是损失函数在其梯度方向上下降即Gradient Boosting算法的思想。

面部特征点定位的思想可以理解为学习一个回归函数F,输入图像I,输出为θ,即特征点的位置,则θ=F(I)。通俗来讲,级联回归模型能够统一为学习多个回归函数{f1,f2,…,fn}: θ=F(I)=fn(fn-1(…f(θ0,I),I)) (3) θi=fi(θi-1,I),i=1,…,n (4) 级联是指当前函数fi的输入依赖于上一级函数fi-1的输出,而每一个fi的学习目标都是逼近特征点的真实位置θ,θ0为初始形状。回归当前形状θi-1与标注位置θi之间的差:Δθi=θi-θi-1。核心公式为 在这里插入图片描述 式中:t表示级联序号;Sˆ(t)表示第t级回归器的形状;rt表示第t级回归器(regressor), 每级回归器学习的即输入的参数都是当前形状与标注形状的差(即上一级回归器更新后的形状)。此处所用的特征可以是灰度值或者其他特征。每个回归器都是由许多棵树(tree)构成,每棵树的参数是根据当前形状和真实形状的坐标差和随机挑选的像素对训练得到。

图6为算法的回归过程,ERT是在学习Tree的过程中,直接将形状(shape)的更新值ΔS存入叶子结点(leaf node),初始位置ΔS在通过所有学习到的Tree后,平均形状(mean shape)加上所有经过的叶子结点的ΔS,即可得到最终的人脸关键点位置,图7为算法检测到的关键点。 在这里插入图片描述 图6 算法的回归过程 在这里插入图片描述 图7 关键点标记

2 表情分类与识别 人脸表情识别在识别表情之前需要检测到人的面部,然后通过分析人面部五官等特点判别此时目标对象所表达的情绪。这需要建立一个判别依据,即分类器。采集一些正样本(各种表情的图像)建立表情库,然后训练分类器,给每一种表情状态贴上标签,这是分类器的训练。表情识别过程输入一幅图像,分类器来识别判断这副图像的类别。

支持向量机(support vector machine,SVM)是二类分类模型方法,支持向量机模型是定义在特征空间上的间隔最大的线性分类器,SVM的学习策略是间隔最大化[13]13]。SVM最大分类间隔可以简单理解为存在两类二维数据,若是把数据画在二维坐标平面上,可以很简单用一条线把两类数据分开。理论上这条线可以有无数种,但是,总有一条能够满足靠近这条线的点(正负样本)与这条线的距离最大时便是最好的选择,即是SVM算法所求的决策边界。

一般来讲普通的SVM就是用来完美划分两类数据的一条线,如图8所示。这是最完美的一条直线,该条线处于两类数据的中部且距两类数据一样的距离。而这些离分界线最近的点就是支持向量(Support vector),若是分类高维的点,SVM的分界就是平面或者超平面。支持向量机中最核心的是支持向量,在样本集中定位到某些特定的点作为支持向量,就可以依据这些支持向量计算出分类超平面,然后再依据超平面对类别进行归类划分。SVM是一种有监督式的机器学习分类算法,所以对于给定的训练样本,要确定每个样本的归类是1还是0,即每种样本都需要标注一个确切的类别标签,用来SVM训练。对于样本的特征及其维度,SVM并没有限定,本文采用特征点的几何特征作为训练对象,提取人脸五官68点特征进行分析与记录,并使用SVM分类器进行训练分类识别。

在这里插入图片描述 图8 支持向量机最大分类间隔

二、部分源代码

function varargout = main_gui(varargin)
% MAIN_GUI MATLAB code for main_gui.fig
%      MAIN_GUI, by itself, creates a new MAIN_GUI or raises the existing
%      singleton*.
%
%      H = MAIN_GUI returns the handle to a new MAIN_GUI or the handle to
%      the existing singleton*.
%
%      MAIN_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in MAIN_GUI.M with the given input arguments.
%
%      MAIN_GUI('Property','Value',...) creates a new MAIN_GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before main_gui_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to main_gui_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 main_gui

% Last Modified by GUIDE v2.5 29-Dec-2018 17:29:22

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @main_gui_OpeningFcn, ...
                   'gui_OutputFcn',  @main_gui_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 main_gui is made visible.
function main_gui_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 main_gui (see VARARGIN)

% Choose default command line output for main_gui
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes main_gui wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = main_gui_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;


% --- 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 str img cc
[filename,pathname] = uigetfile({'*.jpg';'*.bmp'},'选择图片');
str = [pathname,filename];
img = imread(str);
cc=imread(str);
subplot(1,3,1),imshow(cc);
set(handles.text5,'string',str);


% --- 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)
close(gcf);




% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global cc img t
load('save.mat');
 mapping=getmapping(8,'u2');%LBP映射
        W=[2,1,1,1,1,1,2; ...
          2,4,4,1,4,4,2; ...
          1,1,1,0,1,1,1; ...
          0,1,1,0,1,1,0; ...
          0,1,1,1,1,1,0; ...
          0,1,1,2,1,1,0; ...
          0,1,1,1,1,1,0]; 
d=[];
 image_size = size(cc);
   dimension = numel(image_size);
   if dimension == 3
      cc=rgb2gray(cc);
   end
   
       X = double(cc);
      X=255*imadjust(X/255,[0.3;1],[0;1]);
  X = imresize(X,[64 64],'bilinear');  %采用'bilinear':采用双线性插值算法扩展为64*64
  H2=DSLBP(X,mapping,W);%提取图片的LBP直方图
  Gray=X;
  Gray=(Gray-mean(Gray(:)))/std(Gray(:))*20+128;
  lpqhist=lpq(Gray,3,1,1,'nh');       %计算每个照片lpq直方图 

  d=[d;a];

P_test=d;
P_test=mapminmax(P_test,0,1);
%%%%%%%%以上是特征提取的部分


%%%%%从这里开始是识别表情的算法,使用支持向量机来识别
addpath SVM-KM  %%添加支持向量机工具箱
c = 100;

kerneloption= 1.3;   %设置核参数
kernel='gaussian'; %设置高斯核作为支持向量机的核函数
[ypred2,maxi] = svmmultival(P_test,xsup,w,b,nbsv,kernel,kerneloption);

   for i=1:length(ypred2)
 
    elseif ypred2(i)==3     t='Fear';  
    elseif ypred2(i)==4    t='Happiness';
    elseif ypred2(i)==5    t='Sad';
    elseif ypred2(i)==6    t='Surprise';
    end
    detector = vision.CascadeObjectDetector;
    bboxes=step(detector,img);
    FrontalFaceCART=insertObjectAnnotation(img,'rectangle',bboxes,t,'color','cyan','TextBoxOpacity',0.8,'FontSize',13);

   end
    set(handles.text10,'string',t);

% --- Executes during object creation, after setting all properties.
function text5_CreateFcn(hObject, eventdata, handles)
% hObject    handle to text5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

load('save.mat');
disp('训练结束');
axes(handles.axes2);
vid = videoinput('winvideo',1,'YUY2_640x480');
set(vid,'ReturnedColorSpace','rgb');
vidRes = get(vid, 'VideoResolution');
nBands = get(vid, 'NumberOfBands');
hImage = image( zeros(vidRes(2), vidRes(1), nBands) );
preview(vid, hImage);
disp('摄像头开启');
faceDetector1 = vision.CascadeObjectDetector;
while(1)
frame = getsnapshot(vid);
box = step(faceDetector1, frame); % Detect faces
if isempty(box)==0
    ff=imcrop(frame,[box(1),box(2),box(3),box(4)]);
%figure;imshow(cc);
    ff=rgb2gray(ff);
%figure;imshow(cc);
    ff=histeq(ff);       %直方图均衡化
%     imwrite(cc,'.\test\1.jpg');
    yy=svm_test(xsup,w,b,nbsv,ff);
    h=rectangle('position',[box(1),box(2),box(3),box(4)],'LineWidth',2,'edgecolor','b');
    for i=1:length(yy)

        end
    end
      pause(0.05);
      set(t1,'string',[]);
      delete(h);
        if strcmpi(get(gcf,'CurrentCharacter'),'c')
         delete(vid);
         disp('程序退出');
         break;
        end

      
else t1=text(10,10, sprintf('未检测到人脸'), 'FontAngle','italic','FontSize',15,'Color','b','FontWeight','Bold');
     pause(0.05);
     set(t1,'string',[]);
     if strcmpi(get(gcf,'CurrentCharacter'),'1')
         delete(vid);
         disp('程序退出');
         break;
     end
end
end

复制代码

三、运行结果

在这里插入图片描述 在这里插入图片描述

四、matlab版本及参考文献

1 matlab版本 2014a

2 参考文献 [1] 蔡利梅.MATLAB图像处理——理论、算法与实例分析[M].清华大学出版社,2020. [2]杨丹,赵海滨,龙哲.MATLAB图像处理实例详解[M].清华大学出版社,2013. [3]周品.MATLAB图像处理与图形用户界面设计[M].清华大学出版社,2013. [4]刘成龙.精通MATLAB图像处理[M].清华大学出版社,2015. [5]姚丽莎,徐国明,房波,何世雄,周欢.结合LBP和SVM的视频表情识别方法[J].山东理工大学学报(自然科学版). 2020,34(04) [6]姚丽莎,张军委,房波,张绍雷,周欢,赵凤.基于LBP和SVM的人脸表情识别系统的设计与实现[J].贵州师范大学学报(自然科学版). 2020,38(01)

分类:
人工智能
分类:
人工智能
收藏成功!
已添加到「」, 点击更改