基于PCA的人脸识别_Matlab实现(个人研读之后的一些总结)
2016-06-05 20:29
906 查看
以下是我在查阅相关文献之后的一些个人的总结,望大神们指正。
“对于一个训练集,100个对象模板,特征是10维,那么它可以建立一个100*10的矩阵,作为样本。求这个样本的协方差矩阵,得到一个10*10的协方差矩阵,然后求出这个协方差矩阵的特征值和特征向量,应该有10个特征值和特征向量,我们根据特征值的大小,取前四个特征值所对应的特征向量,构成一个10*4的矩阵,这个矩阵就是我们要求的特征矩阵,100*10的样本矩阵乘以这个10*4的特征矩阵,就得到了一个100*4的新的降维之后的样本矩阵,每个特征的维数下降了。
利用PCA对图片矩阵进行降维和特征提取(对于特征提取和降维,还可以使用SVD奇异值分解的方法,但是在本文中主要使用的是PCA方法)
训练特征数据规范化
SVM样本训练
测试数据降维
测试特征数据规范化
样本分类
选择图片,选择图片是选择一张图片作为人脸识别使用
图像匹配,就是人脸识别
1. 求平均人脸矩阵:
Xi代表的是一张人脸矩阵
平均人脸矩阵(平均脸)
mA=1n∑i=0nXi
2.求协方差矩阵
T=1n∑i=0n(Xi−mA)(Xi−mA)T
Z=(A-repmat(mA,m,1))
3.求协方差中最大前k个特征向量,利用eigs函数,[V,D]=eigs(T,k),其中V是特征向量,D是特征值(PCA的核心思想就是利用前K个特征向量来代表整个矩阵,达到了降维的效果)
4.V=Z’*V,pcaA=Z*V,降维。
下一篇博客继续
基于PCA的人脸识别
PCA简介
这是百度百科的解析:“对于一个训练集,100个对象模板,特征是10维,那么它可以建立一个100*10的矩阵,作为样本。求这个样本的协方差矩阵,得到一个10*10的协方差矩阵,然后求出这个协方差矩阵的特征值和特征向量,应该有10个特征值和特征向量,我们根据特征值的大小,取前四个特征值所对应的特征向量,构成一个10*4的矩阵,这个矩阵就是我们要求的特征矩阵,100*10的样本矩阵乘以这个10*4的特征矩阵,就得到了一个100*4的新的降维之后的样本矩阵,每个特征的维数下降了。
人脸识别实现的主要步骤
人脸识别主要分为了两个主要的部分,一个是人脸训练,另一个重要的部分是人脸测试。(为了提高识别的准确率,可以首先对图片进行一些预处理,比如是图片的平滑,锐化,小波过滤等等,降低背景,还有图片角度对识别结果的影响)人脸训练部分:
读取训练数据,将图片存到矩阵中。利用PCA对图片矩阵进行降维和特征提取(对于特征提取和降维,还可以使用SVD奇异值分解的方法,但是在本文中主要使用的是PCA方法)
训练特征数据规范化
SVM样本训练
对于人脸识别的部分(其实和人脸训练部分类似):
1.读取测试数据。测试数据降维
测试特征数据规范化
样本分类
附上Matlab GUI代码:
GUI界面包括了三个按钮(faceGui.m)
测试准确率,就是人脸训练,将样本集中的前5张作为训练的样本,将样本中后5张作为测试样本,测试人脸识别的准确率。选择图片,选择图片是选择一张图片作为人脸识别使用
图像匹配,就是人脸识别
global h_axes1; global h_axes2; global edit2; h_f=figure('name','人脸识别系统','position',[300,200,600,400]); %clf reset;%clf 清除当前的图像的所有自图像,Reset重新设置图像的目标属性为默认值 set(h_f,'defaultuicontrolfontsize',12); set(h_f,'defaultuicontrolfontname','宋体'); h_axes1=axes('parent',h_f,'position',[0.2,0.28,0.25,0.56],'Unit','normalized','visible','on'); h_axes2=axes('parent',h_f,'position',[0.55,0.28,0.25,0.56],'Unit','normalized','visible','on'); figcolor=get(h_f,'color'); edit2=uicontrol(h_f,'style','text','position',[150,330,300,40],... 'backgroundcolor',figcolor);%动态变化提示 button_open=uicontrol(h_f,'style','push','string','选择照片'... ,'position',[250 40 100 50],'callback','GUIopen'); button_recg=uicontrol(h_f,'style','push','string','测试准确率',... 'position',[100 40 100 50],'callback','face'); button_match=uicontrol(h_f,'style','push','string','图像匹配',... 'position',[400 40 100 50],'callback','GUIrecg');
人脸训练(face.m)
在人脸训练中,nperson表明了训练样本中含有的含有的人数,设定读取的人脸矩阵的大小为imgrow*imgcol,这个文件主要阐明了人脸训练的步骤clc; clear; npersons=40;%选取40个人的脸 global imgrow; global imgcol;%读取图像的列 global edit2 imgrow=112; imgcol=92;%读取的图像为112*92 set(edit2,'string','读取训练数据....')%显示在句柄为edit2的文本框里 drawnow %更新窗口的内容,不然程序结束时才会显示,这样只能看到最后一句 f_matrix=ReadFace(npersons,0);%读取训练数据 nfaces=size(f_matrix,1);%样本人脸的数量 %低维空间的图像是(npersons*5)*k的矩阵,每行代表一个主成分脸,每个脸20维特征 set(edit2,'string','训练数据PCA特征提取...') drawnow mA=mean(f_matrix);%求每个属性的均值 k=20;%降维至20维 [pcaface,V]=fastPCA(f_matrix,k,mA);%主成分分析法特征提取 %pcaface是200*20 set(edit2,'string','训练特征数据规范化....') drawnow %每次设置完之后要更新窗口内容 lowvec=min(pcaface); upvec=max(pcaface); scaledface=scaling(pcaface,lowvec,upvec); set(edit2,'string','SVM样本训练...') drawnow %每次设置完之后要更新窗口内容 gamma=0.0078; c=128; multiSVMstruct=multiSVMtrain(scaledface,npersons,gamma,c); %save('recognize.mat','multiSVMstruct','npersons','k','mA','V','lowvec','upvec'); set(edit2,'string','读取测试数据...') drawnow [testface,realclass]=ReadFace(npersons,1); set(edit2,'string','测试数据降维...') drawnow m=size(testface,1); for i=1:m testface(i,:)=testface(i,:)-mA; end pcatestface=testface*V; set(edit2,'string','测试特征数据规范化...') scaledtestface=scaling(pcatestface,lowvec,upvec); set(edit2,'string','样本分类...') drawnow class=multiSVM(scaledtestface,multiSVMstruct,npersons); set(edit2,'string','测试完成!') accuracy=sum(class==realclass)/length(class); msgbox(['识别准确率:',num2str(accuracy*100),'%。'])
训练数据(ReadFace.m)
这个文件主要作用是读取训练数据,flag =0是训练样本,flag=1是测试样本。首先设置好训练集的路径,我这里是G:\资料\学习资料\Matlab\人脸库\s1到s40中每个文件夹中有10张人脸图片,这段代码的含义是从s1读到s40,每个文件夹读取其中的前5张图片作为训练样本。最后将所有的人脸样本都保存在f_matrix中function [f_matrix,realclass]=ReadFace(npersons,flag) %读取ORL人脸库照片里的数据到矩阵 %输入: % npersons-需要读入的人数,每个人的前五幅图为训练样本,后五幅为验证样本 % imgrow-图像的行像素为全局变量 % imgcol-图像的列像素为全局变量 % flag-标志,0表示读入训练样本,1表示读入测试样本 %输出: %已知全局变量:imgrow=112;imgcol=92; global imgrow; global imgcol; realclass=zeros(npersons*5,1);%zeros 创建全零数组 矩阵创建了一个200*1的零矩阵 f_matrix=zeros(npersons*5,imgrow*imgcol);%创建了一个200*(112*92)的零矩阵,把训练集中所有的人脸都放在这个f_matrix中 for i=1:npersons facepath='G:\资料\学习资料\Matlab\人脸库\s';%训练样本集的路径 facepath=strcat(facepath,num2str(i));%strcat 字符串拼接 num2str()把数字转为字符串 facepath=strcat(facepath,'\'); cachepath=facepath;%得到图片的路径 for j=1:5 facepath=cachepath; if flag==0 %读入训练样本的数据(matlab中=相当于赋值,==才是比较) facepath=strcat(facepath,'0'+j); else %读入测试样本数据 facepath=strcat(facepath,num2str(5+j)); realclass((i-1)*5+j)=i; end facepath=strcat(facepath,'.pgm'); img=imread(facepath); f_matrix((i-1)*5+j,:)=img(:)';%img(:)转换成112*92行1列 end end end
利用PCA提取样本的特征向量和降维(fastPCA.m)
PCA的计算原理:1. 求平均人脸矩阵:
Xi代表的是一张人脸矩阵
平均人脸矩阵(平均脸)
mA=1n∑i=0nXi
2.求协方差矩阵
T=1n∑i=0n(Xi−mA)(Xi−mA)T
Z=(A-repmat(mA,m,1))
3.求协方差中最大前k个特征向量,利用eigs函数,[V,D]=eigs(T,k),其中V是特征向量,D是特征值(PCA的核心思想就是利用前K个特征向量来代表整个矩阵,达到了降维的效果)
4.V=Z’*V,pcaA=Z*V,降维。
function [pcaA,V]=fastPCA(A,k,mA) %快速PCA,主成分分析 %输入: % A-样本矩阵,每行是一个样本,列是样本的维数 % k-降至k维 % MA 矩阵均值 %输出: % pcaA-降维后的k维样本特征向量组成的矩阵,即主成分 % V-主成分分量 m=size(A,1);%计算有多少个样本 Z=(A-repmat(mA,m,1));%remat复制和平铺矩阵,原矩阵与均值矩阵相减 T=Z*Z';%求协方差矩阵,如果是z'*z则计算的维数为imgrow*imgcol>>npersons*5,∑(x-u)(x-u)'求协方差矩阵,T为200*200 [V,D]=eigs(T,k);%计算T的最大k个特征值和特征向量,V为特征向量,D为特征值,V为200*20 V=Z'*V;%协方差矩阵的特征向量(V是imgrow*imgcol*k) for i=1:k %特征向量单位化 该向量除以该向量的单位长度 l=norm(V(:,i));%求向量的二范数 V(:,i)=V(:,i)/l; end pcaA=Z*V; %线性变换,降至k维 特征脸对人脸的表示(pcaA是npersons*5*k) end
下一篇博客继续
相关文章推荐
- 解析在main函数之前调用函数以及对设计的作用详解
- 详解Matlab中 sort 函数用法
- opencv 做人脸识别 opencv 人脸匹配分析
- java和matlab画多边形闭合折线图示例讲解
- C#调用Matlab生成的dll方法的详细说明
- 人脸识别测颜值、测脸龄、测相似度微信接口
- 简述Matlab中size()函数的用法
- 从java中调用matlab详细介绍
- 从SVD到PCA——奇妙的数学游戏
- 稀疏自动编码器 (Sparse Autoencoder)
- 白化(Whitening):PCA vs. ZCA
- 人脸识别测颜值、测脸龄、测相似度微信接口
- 详解Matlab中 sort 函数用法
- 简述Matlab中size()函数的用法
- VC++与Matlab混合编程的快速实现
- Matlab 矩阵运算
- matlab与opencv部分函数的对照
- matlab神经网络工具箱创建神经网络
- Matlab