PCA主要代码

function [pcaA V] = fastPCA( A, k ) % 快速PCA % % 输入:A --- 样本矩阵,每行为一个样本 %      k --- 降维至 k 维 % % 输出:pcaA --- 降维后的 k 维样本特征向量组成的矩阵,每行一个样本,列数 k 为降维后的样本特征维数 %      V --- 主成分向量  [r c] = size(A);  % 样本均值 meanVec = mean(A);  % 计算协方差矩阵的转置 covMatT Z = (A-repmat(meanVec, r, 1)); covMatT = Z * Z';  % 计算 covMatT 的前 k 个本征值和本征向量 [V D] = eigs(covMatT, k);  % 得到协方差矩阵 (covMatT)' 的本征向量 V = Z' * V;  % 本征向量归一化为单位本征向量 for i=1:k     V(:,i)=V(:,i)/norm(V(:,i)); end  % 线性变换(投影)降维至 k 维 pcaA = Z * V;  % 保存变换矩阵 V 和变换原点 meanVec save('Mat/PCA.mat', 'V', 'meanVec');

function [ xApprox ] = approx( x, k ) % 用 k 个主成分分量来近似(重建)样本 x % % 输入:x --- 原特征空间中的样本,被近似的对象 %       k --- 近似(重建)使用的主分量数目 % % 输出:xApprox --- 样本的近似(重建)  % 读入 PCA 变换矩阵 V load Mat/PCA.mat  nLen = length(x);  xApprox=zeros(1, nLen);  for ii = 1:k     xApprox=xApprox+(x*V(:,ii))*V(:,ii)'; end
function visualize_pc(E) % 显示主成分分量(主成分脸,即变换空间中的基向量) % % 输入:E --- 矩阵,每一列是一个主成分分量   [size1 size2] = size(E); global imgRow; global imgCol; row = imgRow; col = imgCol;  if size2 ~= 20    error('Can only display 20 principle components'); end;  c1 = zeros(row,col*5); c2 = c1; c3 = c1; c4 = c1; c1(:) = E(:,1:5); c2(:) = E(:,6:10); c3(:) = E(:,11:15); c4(:) = E(:,16:20); size(c1)  composite=zeros(row*4,col*5); composite(:)=[c1;c2;c3;c4];  figure; colormap(gray); imagesc(composite);    axis image; m=min(min(composite)); M =max(max(composite)); imwrite(uint8((composite-m)*(255/(M-m))),'composite.tiff'); 

SVM主要代码

function multiSVMStruct = multiSVMTrain(TrainData, nSampPerClass, nClass, C, gamma) %function multiSVMStruct = multiSVMTrain(TrainData, nSampPerClass, nClass, C, gamma) % 采用1对1投票策略将 SVM 推广至多类问题的训练过程,将多类SVM训练结果保存至multiSVMStruct中 % % 输入:--TrainData:每行是一个样本人脸 %     --nClass:人数,即类别数 %     --nSampPerClass:nClass*1维的向量,记录每类的样本数目,如 nSampPerClass(iClass) %     给出了第iClass类的样本数目 %     --C:错误代价系数,默认为 Inf %     --gamma:径向基核函数的参数 gamma,默认值为1 % % 输出:--multiSVMStruct:一个包含多类SVM训练结果的结构体  % 默认参数 if nargin < 4     C = Inf;     gamma = 1; elseif nargin < 5     gamma = 1; end    %开始训练,需要计算每两类间的分类超平面,共(nClass-1)*nClass/2个 for ii=1:(nClass-1)     for jj=(ii+1):nClass         clear X;         clear Y;         startPosII = sum( nSampPerClass(1:ii-1) ) + 1;         endPosII = startPosII + nSampPerClass(ii) - 1;         X(1:nSampPerClass(ii), :) = TrainData(startPosII:endPosII, :);                      startPosJJ = sum( nSampPerClass(1:jj-1) ) + 1;         endPosJJ = startPosJJ + nSampPerClass(jj) - 1;         X(nSampPerClass(ii)+1:nSampPerClass(ii)+nSampPerClass(jj), :) = TrainData(startPosJJ:endPosJJ, :);                           % 设定两两分类时的类标签         Y = ones(nSampPerClass(ii) + nSampPerClass(jj), 1);         Y(nSampPerClass(ii)+1:nSampPerClass(ii)+nSampPerClass(jj)) = 0;                  % 第ii个人和第jj个人两两分类时的分类器结构信息         CASVMStruct{ii}{jj}= svmtrain( X, Y, 'Kernel_Function', @(X,Y) kfun_rbf(X,Y,gamma), 'boxconstraint', C );      end end  % 已学得的分类结果 multiSVMStruct.nClass = nClass; multiSVMStruct.CASVMStruct = CASVMStruct;  % 保存参数 save('Mat/params.mat', 'C', 'gamma');  
function class = multiSVMClassify(TestFace, multiSVMStruct) % 采用1对1投票策略将 SVM 推广至多类问题的分类过程 % 输入:--TestFace:测试样本集。m*n 的2维矩阵,每行一个测试样本 %     --multiSVMStruct:多类SVM的训练结果,由函数 multiSVMTrain 返回,默认是从Mat/multiSVMTrain.mat文件中读取 % % 输出:--class: m*1 列向量,对应 TestFace 的类标签   % 读入训练结果 if nargin < 2     t = dir('Mat/multiSVMTrain.mat');     if length(t) == 0         error('没有找到训练结果文件,请在分类以前首先进行训练!');     end     load('Mat/multiSVMTrain.mat'); end  nClass = multiSVMStruct.nClass; % 读入类别数 CASVMStruct = multiSVMStruct.CASVMStruct; % 读入两两类之间的分类器信息    %%%%%%%%%%%%%%%%%%%%%%%% 投票策略解决多类问题 %%%%%%%%%%%%%%%%%%%%%%%%%%%%% m = size(TestFace, 1); Voting = zeros(m, nClass); % m个测试样本,每个样本nPerson 个类别的投票箱  for iIndex = 1:nClass-1     for jIndex = iIndex+1:nClass         classes = svmclassify(CASVMStruct{iIndex}{jIndex}, TestFace);          % 投票         Voting(:, iIndex) = Voting(:, iIndex) + (classes == 1);         Voting(:, jIndex) = Voting(:, jIndex) + (classes == 0);                      end % for jClass end % for iClass    % final decision by voting result [vecMaxVal, class] = max( Voting, [], 2 ); %display(sprintf('TestFace对应的类别是:%d',class));

 
  

 
  

 训练过程主要代码

function train(C, gamma) % 整个训练过程,包括读入图像,PCA降维以及多类 SVM 训练,各个阶段的处理结果分别保存至文件: %   将 PCA 变换矩阵 W 保存至 Mat/PCA.mat %   将 scaling 的各维上、下界信息保存至 Mat/scaling.mat %   将 PCA 降维并且 scaling 后的数据保存至 Mat/trainData.mat %   将多类 SVM 的训练信息保存至 Mat/multiSVMTrain.mat   global imgRow; global imgCol; global SVM;   display(' '); display(' '); display('训练开始...');  nPerson=40; nFacesPerPerson = 5; display('读入人脸数据...'); [imgRow,imgCol,FaceContainer,faceLabel]=ReadFaces(nFacesPerPerson,nPerson); display('..............................');   nFaces=size(FaceContainer,1);%样本(人脸)数目  display('PCA降维...'); [pcaFaces, W] = fastPCA(FaceContainer, 20); % 主成分分析PCA % pcaFaces是200*20的矩阵, 每一行代表一张主成分脸(共40人,每人5张),每个脸20个维特征 % W是分离变换矩阵, 10304*20 的矩阵 visualize_pc(W);%显示主成分脸 display('..............................');  X = pcaFaces;  display('归一化开始...'); display('.........'); [X,A0,B0] = scaling(X); save('Mat/scaling.mat', 'A0', 'B0'); % 保存 scaling 后的训练数据至 trainData.mat TrainData = X; trainLabel = faceLabel; save('Mat/trainData.mat', 'TrainData', 'trainLabel'); display('归一化完成...');  display('训练分类器开始,这个过程可能会花上几分钟.........................'); if(get(SVM,'value')==1)     for iPerson = 1:nPerson         nSplPerClass(iPerson) = sum( (trainLabel == iPerson) );     end      multiSVMStruct = multiSVMTrain(TrainData, nSplPerClass, nPerson, C, gamma);     display('正在保存SVM训练结果...');     save('Mat/multiSVMTrain.mat', 'multiSVMStruct'); else display('..............................'); display('训练完成。');







测试效率主要代码

function test() % 测试对于整个测试集的识别率 % % 输出:accuracy --- 对于测试集合的识别率  global SVM; global Adaboost;  display(' '); display(' '); display('测试开始...');  nFacesPerPerson = 5; nPerson = 40; bTest = 1; % 读入测试集合 display('读入测试集合...'); [imgRow,imgCol,TestFace,testLabel] = ReadFaces(nFacesPerPerson, nPerson, bTest); display('..............................');  % 读入相关训练结果 display('载入训练参数...');      load('Mat/PCA.mat');     load('Mat/scaling.mat');     load('Mat/trainData.mat');     load('Mat/multiSVMTrain.mat');     display('..............................');      % PCA降维     display('PCA降维处理...');     [m n] = size(TestFace);     TestFace = (TestFace-repmat(meanVec, m, 1))*V; % 经过pca变换降维     TestFace = scaling(TestFace,1,A0,B0);     display('..............................');      % 多类 SVM 分类     display('测试集识别中...');     classes = multiSVMClassify(TestFace);     display('..............................');      % 计算识别率     nError = sum(classes ~= testLabel);     accuracy = 1 - nError/length(testLabel);     display(['PCA+SVM对于测试集200个人脸样本的识别率为', num2str(accuracy*100), '%']);   

 




识别主要代码

function nClass = classify(newFacePath) % 整个分类(识别)过程 global SVM; global Adaboost;  display(' '); display(' '); display('识别开始...');  % 读入相关训练结果 display('载入训练参数...');      load('Mat/PCA.mat');     load('Mat/scaling.mat');     load('Mat/trainData.mat');     load('Mat/multiSVMTrain.mat');          display('..............................');      xNewFace = ReadAFace(newFacePath); % 读入一个测试样本     xNewFace = double(xNewFace);     xNewFace = (xNewFace-meanVec)*V;% 经过pca变换降维     xNewFace = scaling(xNewFace,1,A0,B0);       display('身份识别中...');     nClass = multiSVMClassify(xNewFace);     display('..............................');     display(['身份识别结束,类别为:' num2str(nClass), '。']);