基于PCA和SVM的人脸识别
程序的流程主要分为三部分,数据的预处理(PCA降维和规格化),数据的训练阶段,数据的识别阶段
数据的预处理的流程图如下:
数据的训练流程图如下:
识别流程:
下面贴上一些matlab的实现代码:
数据预处理主要是两个函数,ReadFaces和scaling,第一个函数是将训练图像存成一个200*10304的矩阵,第二个是对数据进行规格化,具体代码如下:
function [imgRow,imgCol,FaceContainer,faceLabel] = ReadFaces(nFacesPerson,nPerson,bTest)
%nFacesPersonn-----每个人需要读入的样本数,默认为5
%nPerson ------需要读入的人数,默认为全部四十个人
%bTest ------bool型参数。默认为0,表示读入样本前五张;1:表示后五张
%输出: FaceContainer------向量化人脸容器,nPerson*10304的二维矩阵,每行对应一个人脸向量
if nargin==0 %默认值
nFacesPerson = 5;
nPerson = 40;
bTest = 0;
elseif nargin<3
bTest = 0;
end
img=imread('PCA_face/data/ORL/s1_1.bmp') %为计算尺寸先读一张
[imgRow,imgCol]=size(img);
FaceContainer = zeros(nFacesPerson*nPerson,imgRow*imgCol);
facelabel = zeros(nFacesPerson*nPerson,1);
%读入训练数据
for i=1:nPerson %不同的人
i1=mod(i,10);
i0=char(i/10);
strPath='PCA_face/data/ORL/s';
if(i0~=0)
strPath=strcat(strPath,'0'+i0);
end
strPath=strcat(strPath,'0'+i1);
strPath=strcat(strPath,'_');
tempStrPath=strPath;
for j=1:nFacesPerson %每一个人的前五张
strPath=tempStrPath;
if bTest==0
strPath=strcat(strPath,'0'+j);
else
strPath=strcat(strPath,num2str(5+j));
end
strPath = strcat(strPath,'.bmp');
img=imread(strPath);
%把读入的图像按列存储为行向量放入向量化人脸容器FaceContainer的对应行中
FaceContainer((i-1)*nFacesPerson+j,:)= img(:)';
faceLabel((i-1)*nFacesPerson+j) = i;
end
end
%保存人脸样本矩阵
save('PCA_face/Mat/FaceMat.mat','FaceContainer');
function [ SVFM, lowVec,upVec ] = scaling( VecFeaMat,bTest,lRealBVec,uRealBVec)
% Input: VecFeaMat --- 需要scaling的 m*n 维数据矩阵,每行一个样本特征向量,列数为维数
% bTest --- =1:说明是对于测试样本进行scaling,此时必须提供 lRealBVec 和 uRealBVec
% 的值,此二值应该是在对训练样本 scaling 时得到的
% =0:默认值,对训练样本进行 scaling
% lRealBVec --- n维向量,对训练样本 scaling 时得到的各维的实际下限信息
% uRealBVec --- n维向量,对训练样本 scaling 时得到的各维的实际上限信息
%
% output: SVFM --- VecFeaMat的 scaling 版本
% upVec --- 各维特征的上限(只在对训练样本scaling时有意义,bTest = 0)
% lowVec --- 各维特征的下限(只在对训练样本scaling时有意义,bTest = 0)
if nargin<2
bTest=0;
end
lTargB=-1;
uTargB=1;
[m n] = size(VecFeaMat);
if bTest
if nargin<4
error('to do scaling on test,param must 4');
end
if nargout>1
error('when do scaling ,only one output is supported');
end
for iCol = 1:n
if lRealBVec(iCol)==uRealBVec(iCol)
SVFM(:,iCol) = uRealBVec(iCol);
SVFM(:,iCol) = 0;
else
SVFM(:,iCol) = lTargB + ( VecFeaMat(:,iCol) - lRealBVec(iCol) ) / ( uRealBVec(iCol) - lRealBVec(iCol) ) * ( uTargB - lTargB );
end
end
else %bTest = 0
upVec = zeros(1,n);
lowVec= zeros(1,n);
for iCol = 1:n
lowVec(iCol) = min( VecFeaMat(:,iCol) );
upVec(iCol) = max( VecFeaMat(:,iCol) );
if lowVec(iCol) == upVec(iCol)
SVFM(:,iCol) = upVec(iCol);
SVFM(:,iCol) = 0;
else
SVFM(:,iCol) = lTargB + ( VecFeaMat(:,iCol) - lowVec(iCol) ) / ( upVec(iCol) - lowVec(iCol) ) * ( uTargB - lTargB );
end
end
end
end
训练阶段的函数是train,代码如下:
function train()
%整个训练过程包括读入图像,PCA降维以及多类SVM训练,各个阶段的处理结果分别保存至文件:
% 将PCA变换矩阵W保存至 PCA_face\Mat\PCA.mat
% 将scaling的各维上下界信息保存至 PCA_face\Mat\scaling.mat
% 将PCA降维并且scaling后的数据保存至 PCA_face\Mat\trainData.mat
% 将多类SVM的训练信息保存至 PCA_face\Mat\multiSVMTrain.mat
global imgRow;
global imgCol;
global W
display('');
display('');
display('训练开始.....');
nPerson = 40;
nFacesPerson = 5;
nSplPerClass=zeros(1,nPerson);
display('读入人脸数据');
[ imgRow, imgCol, FaceContainer, faceLabel] = ReadFaces(nFacesPerson, nPerson);
save('PCA_face\Mat\FaceMat.mat','FaceContainer');
display('..................');
nFaces = size(FaceContainer, 1);%样本人脸数目
display('PCA降维...');
[pcaFaces, W] = fastPCA(FaceContainer, 20);
%pcaFaces是200*20的矩阵,每一行代表一张主成分脸
%W是分离变换矩阵, 10304*20的矩阵
visualize_pc(W);
display('............');
X=pcaFaces;
[X,A0,B0] = scaling(X);
save('PCA_face\Mat\scaling.mat','A0','B0');
%保存scaling的数据至trainData.mat
TrainData = X;
trainLabel = faceLabel;
save('PCA_face\Mat\trainData.mat','TrainData','trainLabel');
display('.........保存scaling的数据至trainData.mat..........');
for iPerson = 1:nPerson
nSplPerClass(iPerson) = sum((trainLabel == iPerson));
end
multiSVMStruct = multiSVMTrain (TrainData, nSplPerClass, nPerson, Inf, 1);
display('正在保存训练结果.....');
save('PCA_face\Mat\multiSVMTrain.mat','multiSVMStruct');
display('训练结束.................');
end
识别阶段的函数是
function class = SVMClassify(TestFace, multiSVMStruct)
%class ------识别出的类别
%TestFace------测试图像转换的行向量经过降维后的1*20的行向量,并经过规定化到-1~+1之间
%multiSVMStruct结构体数组,保存了两两分类的svm结构体信息
if nargin<2
t = dir('PCA_face\Mat\multiSVMTrain.mat');
if length(t) == 0
error('没有找到训练结果');
end
load('PCA_face\Mat\multiSVMTrain.mat');
end
%nClass = multiSVMStruct.nClass;
nClass=40;
%CASVMStruct = multiSVMStruct.CASVMStruct;
CASVMStruct = multiSVMStruct;
%%%%%投票策略解决多类问题
m = size(TestFace, 1);
Voting = zeros(m,nClass);
for iIndex = 1:nClass-1
for jIndex = iIndex+1:nClass
classes = svmclassify(CASVMStruct{iIndex}{jIndex},TestFace);
%voting
Voting(:,iIndex) = Voting(:,iIndex) + (classes==1);
Voting(:,jIndex) = Voting(:,jIndex) + (classes==0);
end
end
%decision by voting
[vecMaxValue, class] = max(Voting, [ ] , 2);
end
基于PCA和SVM的人脸识别的更多相关文章
- 基于PCA和SVM的人脸识别系统-error修改
------------------------------------------------- Undefined function or variable 'W'. Error in class ...
- opencv基于PCA降维算法的人脸识别
opencv基于PCA降维算法的人脸识别(att_faces) 一.数据提取与处理 # 导入所需模块 import matplotlib.pyplot as plt import numpy as n ...
- 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...
- 关于运行“基于极限学习机ELM的人脸识别程序”代码犯下的一些错误
代码来源 基于极限学习机ELM的人脸识别程序 感谢文章主的分享 我的环境是 win10 anaconda Command line client (version 1.6.5)(conda 4.3.3 ...
- C#实现基于ffmepg加虹软的人脸识别
关于人脸识别 目前的人脸识别已经相对成熟,有各种收费免费的商业方案和开源方案,其中OpenCV很早就支持了人脸识别,在我选择人脸识别开发库时,也横向对比了三种库,包括在线识别的百度.开源的OpenCV ...
- C#实现基于ffmpeg加虹软的人脸识别demo及开发分享
对开发库的C#封装,屏蔽使用细节,可以快速安全的调用人脸识别相关API.具体见github地址.新增对.NET Core的支持,在Linux(Ubuntu下)测试通过.具体的使用例子和Demo详解,参 ...
- C#实现基于ffmpeg加虹软的人脸识别
关于人脸识别 目前的人脸识别已经相对成熟,有各种收费免费的商业方案和开源方案,其中OpenCV很早就支持了人脸识别,在我选择人脸 识别开发库时,也横向对比了三种库,包括在线识别的百度.开源的OpenC ...
- 基于Dlib、OpenCV开发人脸识别程序的开发建议
前言 在去年十月的时候参加了一个小比赛,做了一个人脸识别程序并很意外地获得省里面的一等奖,视频演示链接在这里,有同学想要做这方面的毕业设计or课程设计,发一篇博客来分享一下当时的开发过程. 视频演示链 ...
- 基于Python与命令行人脸识别项目(系列一)
Face Recognition 人脸识别 摘要:本项目face_recognition是一个强大.简单.易上手的人脸识别开源项目,并且配备了完整的开发文档和应用案例,方便大家使用.对于本项目可以使用 ...
随机推荐
- 使用nvm来管理nodejs版本
nvm 是 Mac 下的 node 管理工具,有点类似管理 Ruby 的 rvm,如果是需要管理 Windows 下的 node,官方推荐是使用 nvmw 或 nvm-windows .nvm主要用来 ...
- mysql简单练习
数据库入门 2.1 引入 数据保存到内存: 优点: 1)读写非常快 缺点: 1)程序关闭导致数据丢失 数据保存到文件: 优点: 1)数据可以永久保存 缺点: 1)频繁地IO操作,效率不高! 2)数据管 ...
- JS 中的引用
首先有一个全局变量 JsonArry={"key":"value"}; 假设这个object为{"你好":"引用"} ...
- Android较低版本(<5.2) 页面默认Select选择框效果的BUG解决
Bug描述: 使用低版本安卓(<5.2),在微信上打开网页,点击下拉框,会出现如下图所示的用来展示select选项的弹出框: 在选项较少的时候,可以向下滑动,将选项滑到底部 滑动前: 滑动后: ...
- java对象的内存分配
(1) 寄存器(register).这是最快的保存区域,这是主要由于它位于处理器内部.然而,寄存器的数量十分有限,所以寄存器是需要由编译器分配的.我们对此没有直接的控制权,也不可能在自己的程序里找到寄 ...
- ZOJ 3511 不相交切切多边形 线段树求最大边数
题意: n多凸边形 m刀 (把n切m刀,问切完后的图形中 最多的边数 是多少) 切a点-b点 数据保证切的刀不会相交 思路: 2点之间的剩余点数就是边数, 把a-b距离 近 排序 切完一刀就统计一下切 ...
- Python进阶之路---1.5python数据类型-字符串
字符串 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; ...
- 将GridView中的数据导出到Excel代码与注意事项
//gv:需要导出数据的GridView,filename:导出excel文件名 public void ExportToExcel(GridView gv, string filename) { s ...
- Image控件的简单使用示例1
Image控件加载图片包括加载动态图片,加载静态图片两种方式.一.加载动态图片通过生成一个BitmapImage,创建该对象后,赋给Image的Source即可.加载的形式: 示例1 BitmapIm ...
- lnmp架构下php安全配置分享
目录[-] 1. 使用open_basedir限制虚拟主机跨目录访问 2. 禁用不安全PHP函数 3. 关注软件安全资讯 4. php用户只读 5. 关闭php错误日志 6. php上传分离 7. 关 ...