PCA降维+SVM 算法进行人脸识别
SVM基本原理:
给定训练样本集,在特征空间上找到一个分离超平面,将样本点分到不同的类。 其中当且存在 唯一 的分类超平面, 使得样本点距离分类超平面的距离最大。其中距离超平面最近的点为该超平面的支持向量。
找到超平面后,对于待测点,通过计算该点相对于超平面的位置进行分类。当点距离超平面的距离越大,表示分类预测的确信程度越高。
惩罚参数表示对误分类点的惩罚权重。 惩罚参数的设置相当与在训练集的误差和间隔平面的距离上做一个折衷选择。当惩罚参数过大,容易出现过拟合的情况, 预测时,易导致误分情况。减小惩罚参数,开始容忍样本点落入间隔平面之内,惩罚参数过小会导致训练集的样本点对结果影响变小,分类功能丧失。因此,选择合适惩罚参数,会大大提高分类器的性能,非常关键。 实际运用过程中,采用交叉验证的方法可以选择合适的参数 C。
实际的训练集通常是线性不可分,这就需要运用到核技巧将原空间中点映 射到线性可分的高维空间。 常用的核 函数有:线性核函数、多项式核函数,高斯核函数( RBF 核函数 ), sigmoid 核函数 。
人脸库:
本文所用的人脸库来自埃塞克斯大学的faces人脸库,从中选取了13张人脸,每张人脸有10张图片,选取前5张作为训练集,后5张作为测试集,来检验识别的准确性。最终的人脸识别测试则另选10张图片以外的图片。
在13个人的5个测试图片检验下,SVM算法可以得到100%的准确性。
如图所示,是利用SVM算法进行人脸识别的效果
matlab代码如下(列出了PCA降维以及识别部分的函数):
%%
clc,clear
npersons=13;%选取13个人的脸
global imgrow;
global imgcol;
imgrow=200;
imgcol=180;
%%
%读取训练数据
[f_matrix,train_label]=ReadFace(npersons,0);%读取训练数据
nfaces=size(f_matrix,1);%样本人脸的数量
%低维空间的图像是(nperson*5)*k的矩阵,每行代表一个主成分脸,每个脸20维特征
%对训练集进行降维处理
mA=mean(f_matrix);
k=20;%降维至20维
[train_pcaface,V]=fastPCA(f_matrix,k,mA);%主成分分析法特征提取
%显示主成分脸,即特征脸,低维的基
visualize(V)%显示主分量脸 ,即特征脸
%低维训练集归一化
lowvec=min(train_pcaface);
upvec=max(train_pcaface);
train_scaledface = scaling( train_pcaface,lowvec,upvec);
%SVM样本训练
model = libsvmtrain(train_label,train_scaledface,'-t 0');
%读取测试数据
[test_facedata,test_facelabel]=ReadFace(npersons,1);
%测试数据降维
%test_pcatestface-测试数据低维空间的表示
m=size(test_facedata,1);
for i=1:m
test_facedata(i,:)=test_facedata(i,:)-mA;
end
test_pcatestface=test_facedata*V;
%测试数据归一化
scaled_testface = scaling( test_pcatestface,lowvec,upvec);
%利用训练集建立的模型,对测试集进行分类
[predict_label,accuracy,decision_values]=libsvmpredict(test_facelabel,scaled_testface,model);
%人脸识别模块
recognition(mA,V,model) ;
function [ pcaA,V] = fastPCA( A,k,mA)
mean(f_matrix)
m=size(A,1); %m为读取图片的张数
Z=(A-repmat(mA,m,1));
T=Z*Z';
[V1,D]=eigs(T,k);%计算T的最大的k个特征值和特征向量
V=Z'*V1;
for i=1:k %特征向量单位化
l=norm(V(:,i));
V(:,i)=V(:,i)/l;
end
pcaA=Z*V;
end
function recognition(mA,V,model)
%函数作用:人脸识别模块,利用已经建好的模型,重新找一个样本进行识别
%输入:
% mA-均值
% V-协方差矩阵特征向量
% model-通过SVM对训练集训练得出的已经建立好的模型
%%
global imgrow;
global imgcol;
imgrow=200;
imgcol=180;
%%
%弹出输入框,选择要识别的图片
select_person_num=str2double(cell2mat(inputdlg('请输入想要识别的人的编号(总共13个人):')));%总共13个人
select_img_num=str2double(cell2mat(inputdlg('请输入此人图片的编号:')));%总共10张图
%%
%对图片信息进行处理
select_facepath=strcat('.\TestDatabase\',num2str(select_person_num),'\',num2str(select_img_num),'.jpg');
select_img=imread(select_facepath);
select_img=rgb2gray(select_img);
select_matrix=zeros(1,imgrow*imgcol);
select_matrix(1,:)=select_img(:)';
select_matrix=(select_matrix-mA)*V;%PCA降维后的低维表示
%%
%图形归一化
select_matrix = scaling( select_matrix,min(select_matrix),max(select_matrix));
%%
%测试选择的图片,accuracy只有两个值,100%表示匹配正确,0%表示匹配错误
[select_predict_label,accuracy,decision_values]=libsvmpredict(select_person_num,select_matrix,model);
%%
%显示原有图片和匹配图片进行比较
figure(2);
subplot(1,2,1);imshow(select_img);title('你选择的图片');
subplot(1,2,2);
imshow(imread(strcat('.\TrainDatabase\',num2str(select_predict_label),'\',num2str(1),'.jpg')));
title('匹配的图片');