此文章中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 内存放SVM训练和分类函数 multiSVMTrain.m 和 multiSVMClassify.m文件
6.1 多类问题训练函数