(一)基于MatLab的PCA降维人脸识别系统

本次博客内容将详细介绍如何使用MatLab,进行PCA降维来识别人脸。内容参考张铮《精通MatLab数字图像处理与识别》。书中有些内容应该是出现了打印错误,再次对部分算法进行改正,补充了书中没有的函数,此次博客内容仅适用于新手入门。部分背景,介绍描述性语言都省略,想看详细的内容,请看书籍内容。
1. 实验使用器材
MatLab、ORL人脸库
其中ORL人脸库来源:http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html :
2. ORL人脸库简单介绍
数据库中一共有400张人脸图(40人,每人10张,大小 112*92)
数据库中光照姿势等变化都不大

  1. 实验结果
    采用维度 C gamma 识别率
    20 inf 1 12,5%
    100 inf 1 26.5%
    200 inf 1 53.0%
    200 128 0.0078125 77.5%
    实验得到结果与书中得到结果不相符。

4.理论介绍

(1)PCA降维
如果将一个图像的每一个像素点看成一个特征,我们将得到一幅图像会具有 112*92 = 10304个特征点,在这里可以看成是10304维。自然而然,如此庞大的维度计算量是相当的大,而且在如此高维度下会出现维度灾难,也就是高维度会使得识别率逐渐降低。所以我们要将图像进行降维到一定的维度。接下来将说到如何进行降维。
上一段中提到了一幅图像将拥有‘10304个特征点‘,也就是我们可以换成是1 * 10304 的矩阵,1表示一张图,10304表示112 * 92 。例如2 * 10304 表示 两张 112 * 92的图像。此时将用到函数: ReadFaces

function [imgRow,imgCol,FaceContainer,faceLabel] = ReadFaces(nFacePerPerson,nPerson,bTest)
%读入ORL人脸库的指定数目的人脸前五张(训练)
%输入:nFaceperperson:每个人需要读入的样本数
% nPerson:需要读入的人数,默认为全部40人
% bTest:bool型参数。默认为0(读入训练样本前五张),1表示后五张
%输出:FaceContainer:人脸容器,nperson * 10304 的2维矩阵,每行对应一个人脸向量
if nargin == 0
nFacePerPerson = 5;
nPerson = 40;
bTest = 0;
elseif nargin < 3
bTest = 0;
end
img = imread(‘DATA/ORL/S1/1.pgm’);
[imgRow,imgCol] = size(img);

FaceContainer = zeros(nFacePerPerson * nPerson,imgRow*imgCol);
faceLabel = zeros(nFacePerPerson*nPerson,1);

%读入训练样本
for i = 1:nPerson
i1 = mod(i,10);
i0 = char(i/10);
strPath = ‘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:nFacePerPerson
strPath = tempStrPath;
if bTest == 0 %读入训练数据
strPath = strcat(strPath,’0’+j);
else
strPath = strcat(strPath,num2str(5+j));
end

    strPath = strcat(strPath,'.pgm');img = imread(strPath);FaceContainer((i-1)*nFacePerPerson + j,:) = img(:);faceLabel((i-1)*nFacePerPerson+j) = i;
end %j

end %i

save(‘Mat/FaceMate.mat’,’FaceContainer’)

通过该函数能够得到一个人脸的容器:其中规定了 当bTest = 0 时,将训练样本。当bTest = 1 时开始测试样本。

为什么要训练样本?得到的这个人脸的容器有什么用?
接下来利用得到的人脸容器FaceContainer进行PCA降维。
人脸容器中 具有 200 * 10304 矩阵,每一行为人脸信息。其中降维,我在线性代数中理解为得到相应的单位特征向量,这些单位特征向量就是维度。具体可以学习线性代数中关于空间变换的知识。
将空间中的大量的点,在一定维度下进行投影(可以理解为在一定维度在进行表示):可以得到一个推广公式
x = m + a1*e1+a2*e2+a3*e3……. x为样本,m为均值,e表示的就是单位特征向量。
为什么会得到这样的一个推广公式? (第一次写博客,公式推导省略一下,其实原理很简单)
虽然多维度的点能在一定维度下表示了,但是怎么确定直线e的方向来使得平方误差E最小呢。这里抛出了直线e的方向和平方误差。何为直线e的方向?当在1维时,直线e就一根,它可以指着任何方向。当在2维时,直线e维两个互相垂直,也可以朝着任意方向,所以推广以后,直线e我们只知道了它是相互垂直,但是具体的方向我们是可以任意确定了。平方误差E和直线e方向有什么关系呢?e的方向将会决定e向量的值,E中会使用到e的运算。使用平方误差的意义,E = ( ||(m+a1 * e)-x1 || +||(m+a2 * e)-x2 || +||(m+a3 * e)-x3 || +….. )^2就是将降维(投影)后的点与实际样本点的差值平方。如果差值越小,说明这些方向上的e能够尽量更好的表示这些点。于是打开平方(这里说的打开并不是直接这样打开,E表示的时候使用累加符号表示的)在运算过程中出现了 S 散布矩阵。并且求解这个最小值变为了带有约束条件的求解问题,使用拉格朗日乘数法。就得到了S * e = namda * e ,namda为特征值,e为特征向量,S取最大,E将最小,则在n维下,依次取最大的特征值即可。所以,降维至n维,就是取n个特征向量运算得到a = e*(x-m)
在这里要说一下,可能会有读者看不明白,S矩阵如何计算得出,S矩阵的得出为什么与取最大特征值对应的特征向量有关?请在网上搜索,主成分分析的理论基础,再结合本文,应该能解决您的疑惑。
解决了一般的PCA降维理论以后可以进行实验了,但是,再运算时发现,维度太大,内存耗尽,为什么呢。原因出在了S矩阵上,所以这里引出了快速PCA降维,原理很简单,就是对S * e = namda * e进行简单的一些变换。下面使用函数 fastPCA
function [pcaA,V] = fastPCA(A,k)
%快速PCA
%输入: A:样本矩阵
% K:降维至k维
%输出: pcaA:降维后,由特征向量组成的特征矩阵,每行一个样本,列数为维度k
% V:主成分向量
if nargin == 0
display(‘参数不足’)
else
[r,c] = size(A);
meanVec = mean(A);
%计算协方差矩阵的转置
Z = (A - repmat(meanVec,r,1));
covMatT = Z* Z’;
%计算convMatT的前K个特征值和特征向量
[V,D]=eigs(covMatT,k);
%得到协方差矩阵的特征向量
V = Z’ * V;
%特征向量转为单位向量
for i = 1:k
V(:,i) = V(:,i) / norm(V(:,i));
end
pcaA = Z*V;
%保存变换矩阵V和变换原点meanVec
save(‘Mat/PCA.mat’,’V’,’meanVec’);
end
其中A,就是人脸容器
留下问题,为什么要训练样本?

  1. 开始准备操作

    接下来就主成分脸进行可视化。
    其中visualize_pc,再PCA_main函数后面,注意一下,别复制错了
    

function PCA_main(k)
%ORL 人脸采集的主成分分析
%输入k : 降维至k
global imgRow;
global imgCol;
nPerson = 40;
nFacePerPerson = 5;
disp(‘读入人脸数据。。。。’);
[imgRow,imgCol,FaceContainer,faceLabel] = ReadFaces(nFacePerPerson,nPerson);
disp(‘………………’)
nFaces = size(FaceContainer,1);%样本人脸数目
disp(‘PCA降维’);
% LowDimFace nPerson*nFacePerPerson行,k列,每行代表一张主成分脸,每个脸k个维特征
% W是分离变换矩阵
[LowDimFace,W] = fastPCA(FaceContainer,k);
visualize_pc(W);%显示主成分脸
save(‘Mat/LowDimFace.mat’,’LowDimFace’);
disp(‘计算结束’);


function visualize_pc(E)
% 显示主成分分量(主成分脸,即变换空间中的基向量)
%输入E 每一列是主成分分量

[size1,size2] = size(E);
global imgRow;
global imgCol;
row = imgRow;
col = imgCol;
if size2 ~=20
error(‘只用于显示20个主成分’);
end
figure
img = zeros(row,col);
for ii = 1:20
img(:) = E(:,ii);
subplot(4,5,ii);
imshow(img,[]);
end

  1. 支持向量机SVM
    使用SVM,本来它时一个二分器,此时我们用一定的策略来解决多分类问题。在这里,使用一对一的投票策略
    这里引入了MatLab自带的函数: SVMStruct函数、svmclassify函数
  2. 数据的规格化
    为什么要进行数据的规格化。ABC三人:A: 1.8m 70kg B:1.6m,70 kg C:1.8m,60,由于数据没有规格化,原本身高差距与体重之间的数值差异会影响到分类。所以此处引出了规格化的函数 对降维后的数据进行规格化:scaling

function [SVFM,lowVec,upVec] = scaling(VecFeaMat,bTest,lRealBVec,uRealBVec)
%训练样本时,输入上下限无意义,将得到上下限,并且得到训练样本的规格化向量 ;测试样本时提供上下限可以得到测试样本规格化向量
% 输入 VecFeaMat – 需要规格化的m*n矩阵,其中每行一个特征向量,列数为维度
% bTest – 1:说明此时是对测试样本进行规格化,此时必须提供l,u,此2值是在训练样本规格化时得到
% – 0:默认值,对训练样本进行规格化
% lRealBVec – n维向量,对训练样本规格化时得到的各维的实际下限lowVec
% uRealBVec – n维向量,对训练样本规格化时得到的各维的实际上限upVec
%输出 SVFM – VecFeaMat的规格化版本
% lowVec – 各维特征的下限(只在对训练样本规格化是有意义,bTest = 0)
% upVec – 各维特征的下限(只在对训练样本规格化是有意义,bTest = 0)
if nargin < 2
bTest = 0;
lRealBVec=-1;
uRealBVec= 1;
end
%缩放目标范围[-1,1]
lTargB = -1;
uTargB = 1;
[m,n] = size(VecFeaMat);
SVFM = zeros(m,n);
if bTest
if nargin < 4
error(‘测试样本时需要提供uRealB,lRealB’);
end
if nargout > 1
error(‘当测试样本时,只提供一个输出,SVFM’)
end
for iCol = 1:n
if uRealBVec(iCol) == lRealBVec(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 %训练样本
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)
SVMF(:,iCol) = upVec(iCol);
SVMF(:,iCol) = 0;
else
SVFM(:,iCol) = lTargB+(VecFeaMat(:,iCol)-lowVec(iCol))/(upVec(iCol)-lowVec(iCol))*(uTargB-lTargB);
end
end
end

  1. 确定使用核函数
    核函数将影响到训练结果,直到影响分类。具体原因,有机会再说。这里使用径向基核函数
    function K = kfun_rbf(U,V,gamma)
    %RBF 径向基核函数
    [m1,n1] = size(U);
    [m2,n2] = size(V);
    K = zeros(m1,m2);

for ii = 1:m1
for jj = 1:m2
K(ii,jj) = exp(-gamma*norm(U(ii,:)-V(jj,:))^2);
end
end

  1. 训练
    CASVMStruct{ii}{jj},其中表示为

基于MatLab的PCA降维人脸识别系统(超详细解说)相关推荐

  1. 基于 PCA 的人脸识别系统及人脸姿态分析

    文章目录 1 PCA 1.1 原理 1.2 算法流程 1.2.1 零均值化 1.2.2 计算协方差矩阵 1.2.3 特征值和特征向量 1.2.4 降维得到 K 维特征 1.2.5 PCA 的优缺点 2 ...

  2. 【CSDN下载】第三期:多AGV调度系统软件、基于PCA的人脸识别系统

    为便于广大开发者对热门资源的下载需求,下载频道专为广大开发者开辟了推荐一周IT优质资源通道,以供开发者参考下载,同时欢迎大家上传优质资源并留言所需的资源,小编会汇总所需,及时奉上所求. 工具安装包系列 ...

  3. 基于opencv和pillow实现人脸识别系统(附demo)

    更多python教程请到友情连接: 菜鸟教程https://www.piaodoo.com 初中毕业读什么技校 http://cntkd.net 茂名一技http://www.enechn.com p ...

  4. 基于MATLAB图像处理的硬币个数识别系统

    基于MATLAB图像处理的硬币个数识别系统 1.课题介绍 本设计为基于MATLAB的硬币图像识别统计装置,通过数码相机获取平铺无重叠堆积的硬币的图像,并通过Matlab工具处理后统计硬币的数目.通过控 ...

  5. 03系统多界面_基于MATLAB的多方法车牌识别系统[带GUI界面+万字技术文档+直播]

    一.课题介绍 随着汽车数量的增加,城市交通状况日益受到人们的重视,如何进行有效的交通管理更是成为了人们关注的焦点.智能交通系统通过车辆检测装置对过往的车辆实施检测,提取有关交通数据,达到监控.管理和指 ...

  6. matlab 图像模板匹配,基于MATLAB模板匹配的车牌识别系统

    一.课题名称[Q1321814823] 基于MATLAB模板匹配的车牌识别系统 二.课题背景 随着汽车数量的增加,城市交通状况日益受到人们的重视,如何进行有效的交通管理更是成为了人们关注的焦点.针对此 ...

  7. 【图像处理matlab】PCA+KNN人脸识别 ORL人脸数据集

    文章目录 0.写在前面 1. 数据集导入与划分 2. train-PCA构建脸空间 2.1 原始数据导入 2.2 去中心化 2.3 求解协方差矩阵.特征值.特征向量 2.4 特征脸选取--脸空间 3. ...

  8. 【人脸识别】基于matlab GUI KL变换人脸识别【含Matlab源码 859期】

    ⛄一.KL变换人脸识别简介 人脸识别是指基于己知的人脸样本集,利用图像处理和模式识别的技术从静态或动态场景中,识别或验证一个或多个人脸.人脸识别技术跨越了图像处理.模式识别.计算机视觉.生物学.神经生 ...

  9. 基于opencv和pillow实现人脸识别系统(附详细源代码)

    本文不涉及分类器.训练识别器等算法原理,仅包含对其应用(未来我也会写自己对机器学习算法原理的一些观点和了解) 首先我们需要知道的是利用现有框架做一个人脸识别系统并不难,然后就开始我们的系统开发吧. 我 ...

最新文章

  1. BTC引领市场多头情绪爆发 BCH筑底完成望成上涨新风口
  2. 从青年基金到面上项目
  3. Memcached Client 使用手册
  4. [UE4]增加观察者
  5. 本周DOT将解锁302.47万枚,上周共质押919.9万枚
  6. JAVA浮点数浮点数转换成人民币读法
  7. 2019牛客多校第六场H Pair(数位DP 多个数相关)题解
  8. Sass中使用@each循环
  9. 表锁 行锁 页锁 是什么区别
  10. Visual Basic 2010中文版从入门到精通pdf
  11. c++复习日记3 模板和流
  12. python打印网页成pdf_html – 在chrome-python 2.7中自动打印/保存网页为pdf
  13. Python-开根号的几种方式
  14. 微信小程序商城API文档
  15. 探索性测试的概念及方法
  16. java 判断数字是否连续,JAVA 判断是否连续字母或者数字
  17. springboot+nodejs+vue+elementui教师下乡支教岗位申请系统java项目源码
  18. Python数据分析与挖掘——回归模型的假设检验
  19. 龙芯电脑开启串口的console控制台配置
  20. openssl工具详解及自建CA方法

热门文章

  1. 每个公司老板容易忽略的危机
  2. 视频教程-Python全栈开发入门课-Python
  3. java计算机毕业设计vue校园菜鸟驿站管理系统(附源码、数据库)
  4. 代码静态分析工具-splint的学习与使用[转]
  5. 推荐一波2018年让人惊喜的手机小众APP
  6. 干货:如何有效的做好工程采购、分包及合同管理?
  7. 预防网站被攻击的5种方法,看过来
  8. HDU - 1408 盐水的故事
  9. 图像的均方差MSE和PSNR计算
  10. Python+Vue计算机毕业设计小区停车信息管理系统u4mty(源码+程序+LW+部署)