基于PCA和SVM人脸识别之二.MATLAB实现

此文章中MATLAB实现均根据《数字图像处理与机器视觉----Visual c++ 与MATLAB实现》一书,我所获得的基础知识也大多源于此书,感谢!

                          

下面将我根据教程建立的工程以及敲击的代码块一一奉上,供日后参阅。

建立以专门文件夹FaceRec,地址E:\matlab_2016b_app\bin\FaceRec。

1.  E:\matlab_2016b_app\bin\FaceRec\Data 内存放ORL文件。

2.  E:\matlab_2016b_app\bin\FaceRec\exportLibSVM 内存放export.m文件,以及由export( )函数生成的txt文件。

function export(strMat,strLibSVM)
%{
name: export()函数
fuction:用于从matlab导出libSVM能够使用的格式(.txt)
        此工程要用libSVM的参数选择工具 grid.py,首先需要把数据集 格式化为 grid.py所要求的形式(文本文件)
Input:strMat:源文件名(包括路径),此文件中包含训练数据(traindata)和类标签(trainlabel),该文件可在训练SVM的过程中生成。
              注释:MAT-文件, mat数据格式是matlab的数据存储的标准格式。mat文件是标准的 二进制文件,还可以ASCII码形式保存和加载。
       strLibSVM:目标文件名(包含路径),'.txt'文件,默认为‘traindata.txt’
%}


%默认参数设置
if nargin<1
    strMat ='E:/matlab_2016b_app/bin/FaceRec/Mat/trainData.mat';
    strLibSVM ='E:/matlab_2016b_app/bin/FaceRec/exportLibSVM/trainData.txt';
elseif nargin<2
    strLibSVM ='E:/matlab_2016b_app/bin/FaceRec/exportLibSVM/trainData.txt'
end


[fid,fMsg]= fopen(strLibSVM,'w');   %建立输出文件目标,‘w’为写入,若文件不存在,则创建此新文件
if fid==-1
    disp(fMsg);
    return;
end


strNewLine=[13,10];% 换行。  回车键(软回车)的ASCII码值为13,换行符(硬回车)的值为10; 在windows中换行需要‘软回车+硬回车’!
strBlack=' '; %ASCII码为32(空格)


load(strMat);  %load 打开mat文件.例:load('filename','X','Y','Z') 加载filename文件中的X Y Z变量到工作区间中
[nSamp,nDim]=size(TrainData);  %nSamp 行数(即为样本个数);nDim(列数),即为样本类数。


for iSamp=1:nSamp
    fwrite(fid,num2str (trainLabel(iSamp)),'char' );%写入一个标签(以字符串形式写入)
    for iDim=1:nDim
        fwrite(fid,strBlack,'char');%fwrite(fid,32,'char');
        fwrite(fid,[num2str(iDim) ':'],'char');  %写入列号
        fwrite(fid,num2str(TrainData(iSamp,iDim) ),'char'); %写入该位置 的值
    end
    fwrite(fid,strNewLine,'char'); %换行 fwrite(fid,[13,10],'char');
end


fclose(fid);

    

3.  E:\matlab_2016b_app\bin\FaceRec\Kernel内存放 径向基核函数 kfun_rbf.m文件。

function K=kfun_rbf(U,V,gamma)
%{
name: kfun_rbf(函数)
function: kernel_function-> rbf径向基核函数
          radial basis function: exp(-gamma*|u-v|^2)
Input: U:公式中的X矩阵(m1* n1)
       V:公式中的Y矩阵(m2 *n2)
       gamma; 参数γ(伽马)
Output:K:返回m1*m2维矩阵




SVM 怎样能得到好的结果
1. 对数据做归一化(simple scaling)
2. 应用 RBF kernel
3. 用cross-validation和grid-search 得到最优的c和g
4. 用得到的最优c和g训练训练数据
5. 测试
%}


[m1 n1]=size(U); % m1*n1  %%%%%%%%%%%%%%%%%%%%%%%%%
[m2 n2]=size(V); % m2*n2


K=zeros(m1,m2);  % m1*m2矩阵


for ii=1:m1
    for jj=1:m2
        K(ii,jj)= exp( -gamma * norm(U(ii,:)-V(jj,:) )^2 ); %% rbf函数公式 K(x,y)=exp( -gamma * (x-y)^2 );
    end
end


4.  E:\matlab_2016b_app\bin\FaceRec\Mat内存放 .mat文件,.mat文件中保存有用变量。

5.  E:\matlab_2016b_app\bin\FaceRec\PCA 内存放 fastPCA.m文件

function [pcaA V]=fastPCA(A,k)
%{
name: fastPCA()快速PCA函数
function: 将输入样本矩阵降维(k维)
Input:A---样本矩阵,每行为1个样本
      k---降维至k维
Output:pcaA---降维后的k维矩阵
       V---主成分分量
%}

% A的大小
[m,d]=size(A);

%样本均值
meanVec=mean(A);    %计算各列的均值

%计算协方差矩阵的转置 covMatT
Z= ( A-repmat(meanVec,m,1)  );   %样本矩阵中心化,每一维度减去该维度的均值,使得每一维度的均值为0
                                 %repmat:Replicate Matrix复制和平铺矩阵
covMatT =Z*Z';       %covMatV :(m*d)*(d*m)=m*m

%计算covMatT的前k个本征值和本征向量
[V D]=eigs(covMatT,k);  %V为m*k, k个本征向量; D为k*k,对角线上每一个元素为本征值

%得到协方差矩阵(covMatT')的本征向量
V=Z'*V;

%本征向量归一化为 单位本征向量
for i=1:k
    V(:,i)=V(:,i)/norm(V(:,1));  %norm 为范数,默认为2范数(各分量的平方和 再开根号)
end

%线性变换(投影)降维至k维
pcaA=Z*V;

%保存变换矩阵V和变换原点 meanVec
save('Mat/PCA.mat','V','meanVec');


6.  E:\matlab_2016b_app\bin\FaceRec\SVM

你可能感兴趣的:(matlab,算法)