• 基于PCA和SVM的人脸识别


    程序中采用的数据集是ORL人脸库,该人脸库共有400副人脸图像,40人,每人10幅,大小为112*92像素,同一个人的表情,姿势有少许变化。

    程序的流程主要分为三部分,数据的预处理(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_faceMatPCA.mat
    %   将scaling的各维上下界信息保存至 PCA_faceMatscaling.mat
    %   将PCA降维并且scaling后的数据保存至 PCA_faceMat rainData.mat
    %   将多类SVM的训练信息保存至 PCA_faceMatmultiSVMTrain.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_faceMatFaceMat.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_faceMatscaling.mat','A0','B0');


    %保存scaling的数据至trainData.mat
    TrainData = X;
    trainLabel = faceLabel;
    save('PCA_faceMat rainData.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_faceMatmultiSVMTrain.mat','multiSVMStruct');


    display('训练结束.................');

    end

    识别阶段的函数是

    function class = SVMClassify(TestFace, multiSVMStruct)

    %class  ------识别出的类别

    %TestFace------测试图像转换的行向量经过降维后的1*20的行向量,并经过规定化到-1~+1之间

    %multiSVMStruct结构体数组,保存了两两分类的svm结构体信息
    if nargin<2
        t = dir('PCA_faceMatmultiSVMTrain.mat');
        if length(t) == 0
            error('没有找到训练结果');
        end
        load('PCA_faceMatmultiSVMTrain.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

  • 相关阅读:
    Python2.7-zlib
    Python2.7-sqlite3
    Python2.7-dbm、gdbm、dbhash、bsddb、dumbdb
    Python2.7-anydbm
    Python2.7-marshal
    Python2.7-shelve
    Python2.7-copy_reg
    Python2.7-pickle, cpickle
    Python2.7-shutil
    Python2.7-fnmacth
  • 原文地址:https://www.cnblogs.com/anyuan9/p/6171580.html
Copyright © 2020-2023  润新知