机器视觉4:人脸图像特征提取与分类

(1)实验文件夹中提供facedata数据库,该数据库包括训练数据(train文件夹),该训练数据有40人(每人5张训练照片);测试数据(test文件夹)包括40人(每人5张测试照片)。数据库中还提供了数据归一化函数(scaling),可在训练前将数据进行归一化。
(2)实验推荐按照如下步骤进行程序实现,可将程序分为3大模块(三个函数)实现,分别如下:
①读训练数据模块 Face=ReadFaces(numFaces, nPerson);
nPerson=40; 共40人;
numFaces= 5; 每人5张脸训练;
要求200张人脸每张放一行或者一列,返回20010304大小的人脸数据矩阵Face。
②提取人脸数据矩阵Face的主成分
如: k=49; 49个主成分(可自行定义主成分数量)
[pcaFaces, V, meanVec] =fastPCA(Face, k);
其中:
pcaFaces:维度200
49,数据矩阵Face向V投影后的人脸主成分(每个人脸只有49个特征);
V:维度 1030449 特征协方差矩阵前49个特征向量;
meanVec: 维度1
10304,样本均值。
③主程序模块,在主程序中首先实现,1),2)步骤的数据读取和降维,然后对数据归一化,处理标签数据并置乱,训练,测试,输出准确度函数。

MATLAB代码:

①主函数main.m

clc;clear;close all;
numFaces = 5;
nPerson = 40;
k = 49; %提取主成分个数
% 读取
train_path = './facedata/train/';
Train_Face = ReadFaces(train_path,numFaces,nPerson);

% 降维
[pcaFaces,V,meanVec] = fastPCA(Train_Face,k);
%pcaFace : 人脸主成分,200*49
%V : 特征空间, 10304*49
%meanVec : 样本均值, 1*10304

%归一化
[Traindata, lowVec, upVec] = scaling(pcaFaces);
%Traindata : 200*49  人脸特征

%生成人脸标签
T = zeros(200,40);
for i = 1:40
    for j = 1:5
        T( (i-1)*5+j,i ) = 1;
    end
end
%标签矩阵接到PCA特征后,置乱后训练
gx2(:,1:k) = Traindata;
gx2(:,(k+1):(k+40)) = T;
xd = gx2(randperm(200));
gx = xd(:,1:k);
d = xd(:,(k+1):(k+40));
P = gx';
T = d';
net = newff(P,T,44,{'purelin','purelin'},'traingdx');
net.trainparam.epochs = 5000;
net.trainparam.goal = 0.0001;
net.divideFcn = '';
[net,tr] = train(net,P,T);

Accuracy = TEST(net,V,meanVec,lowVec, upVec)

②ReadFaces.m

function face = ReadFaces(path,numFaces,nPerson)
%读取训练数据,要求200张人脸每张放一行或者一列
%返回200*10304大小的人脸数据矩阵Face
%numFaces = 5; 每人五张人脸照片训练
%nPerson = 40;40file = dir([path 's*']);
%nPerson = length(train_file);
face = [];
for i = 1:nPerson
    t_son_path = [path,file(i).name,'/'];
    pgm = dir([t_son_path,'*.pgm']);
    %numFaces = length(pgm);
    for j = 1:numFaces
        I = imread([t_son_path,pgm(j).name]);
        [m,n] = size(I);
        I = reshape(I,1,m*n);
        face = [face;I];
    end
end
face = double(face);
end

③fastPCA.m

function [pcaFaces,V,meanVec] = fastPCA(Face,k)
%提取人脸数据矩阵Face的主成分
%Face : 人脸数据
%k : 主成分个数
%pcaFaces : 数据矩阵Face向V投影后的人脸主成分
%           每个人了保留k个特征,维度200 * k;
%V: 特征协方差矩阵前k个特征向量;维度10304*k
%meanVec : 样本均值;维度1*10304
    
    %每行为一个样本
    [n,p] = size(Face); %200*10304 
    %样本均值
    meanVec = mean(Face); % 1*10304
   
%     meanFace = uint8(reshape(meanVec,112,92));
%     figure,imshow(meanFace);title('平均脸');
    
    %去中心化
    Z = (Face - repmat(meanVec,n,1)); %200*10304
    %样本协方差矩阵
    covMatT = Z * Z';  %200*200
    
    %计算covMatT的前k个本征值和本征向量
    [V,D] = eigs(covMatT,k);  %200*200
    %V : 主对角线上的特征值,200*k
    %D : 各列中包含对应的特征向量  ,k*k 
    
    %特征脸V:
    V = Z'*V; %10304*k
    
    %本征向量归一化为单位本征向量
    for i = 1:k
        V(:,i) = V(:,i)/norm(V(:,i));
    end
    
    %线性变换(投影)降维至k维
    pcaFaces = Z * V; %200*k = 200*10304 * 10304*k; 
    
end

④scaling.m

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

% 缩放目标范围[-1, 1]
lTargB = -1;
uTargB = 1;


[m n] = size(VecFeaMat);

SVFM = zeros(m, n);

if bTest
    if nargin < 4
        error('To do scaling on testset, param lRealB and uRealB are needed.');
    end
    
    if nargout > 1
        error('When do scaling on testset, only one output is supported.');
    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); % 测试数据的scaling
        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 upVec(iCol) == lowVec(iCol)
            SVFM(:, iCol) = upVec(iCol);
            SVFM(:, iCol) = 0;
        else
            SVFM(:, iCol) = lTargB  +  ( VecFeaMat(:, iCol) - lowVec(iCol) ) / ( upVec(iCol)-lowVec(iCol) ) * (uTargB-lTargB); % 训练数据的scaling
        end
    end
end

⑤TEST.m

function [Accuracy] = TEST(net,V,meanVec,lowVec, upVec)
test_path = './facedata/test/';
file = dir([test_path 's*']);
accu = 0;
for i=1:40
    t_son_path = [test_path,file(i).name,'/'];
    pgm = dir([t_son_path,'*.pgm']);
    for j=1:5 %读入40 x 5 副测试图像
        I = imread([t_son_path,pgm(j).name]);
        b=I(1:10304);
        TestFace=double(b);
        [m,n] = size(TestFace);
        
        TestFace = (TestFace-repmat(meanVec,m,1)) * V;
        TestFace = scaling(TestFace,1,lowVec, upVec);
        X = TestFace;
        Z = sim(net,X');
        [zi,index2] = max(Z);
        if index2 == i
            accu = accu+1;
        end
    end
end
Accuracy = accu/200; %输出识别率
end

实验结果:

机器视觉4:人脸图像特征提取与分类_第1张图片

你可能感兴趣的:(机器视觉,分类,机器学习,人工智能)