墨迹了好一阵不知道从哪下手,终于硬着头皮开始折腾了。打算先借鉴别人做过的~ 对照着代码一点一点抠:
http://blog.csdn.net/hesays/article/details/39498375
--------------------------------- 2015/03/26 ---------------------------------
PCA的基本原理
前几天试着研究了一下主成分分析法(PCA)的原理,离理解透彻还差很远。之前学过的线性代数,由于用得少,基本上还给老师了。有很多基本概念都还不清楚,比如矩阵的特征向量和特征值,特征值分解,基,等等等等。CSDN上有很多大神的解释,看得似懂非懂,像本身不会英语还去查英英词典,对一个问题的解释又会牵扯出更多的问题,实在是看不到头。暂时允许自己不求甚解一次,只阐述主要的部分,在以后的研究中如果有了更深的理解再重新作整理和总结。
1. 为什么需要用到PCA
图像本身的数据量大,导致处理过程的计算量大。但数据之间存在一定的相关性,也就是说这些信息中有大量的冗余。PCA的目的就在于检测并试图去除这种相关性,提取出数据的主要成分,从而降低冗余,提高信息处理的效率。
2. 实现步骤:
使用ORL人脸数据库进行实验,数据库共有400幅图像,40个人每人10幅,图像尺寸为112x92。人为地将数据库分为训练集和测试集:将每个人的前5幅图像作为训练集,用于学习每个人的特征;后5幅图像作为测试集,作为系统的输入,逐个判断其类别,并计算识别率。
①将训练集原始数据中心化(即:均值归零)
②计算协方差矩阵、以及它的特征值和对应的特征向量
③选取最大的k个特征值及其对应特征向量,组成一组新的基
④将测试集图像对这组新的基投影,得到降维后的新特征,即所谓的特征脸
⑤采用恰当的分类准则(例如最小距离准则)判定输入人脸是谁 [待定]
3. 理解难点:为什么通过协方差矩阵的特征值分解,就能得到数据的主成分? [待补充]
--------------------------------- 2015/03/28 ---------------------------------
MATLAB使用入门
1. 前面的内容看起来太高大上了。。打开Matlab还是啥也不会,摔。。先从最简单的入手吧。你都想不到有多简单:我来加载一张图片。
ORL人脸数据库的40个人各有10张图片,分别放在s1,s2,s3,...,s40这样的子文件夹里。如果当前工作路径是s1文件夹,用 imread() 函数读取图片的时候,括号里的内容只需填写文件名+后缀。如果当前工作路径不是s1,那么使用 imread() 时应在括号里给出文件完整路径。
前面所说参考的那篇文章里,作者将400张图片重新命名,比如第16个人的第9张图片命名为 016009,这样文件名中就包含了“该图片属于第几个样本”的信息,感觉对测试时计算识别率可能有用,不知道有没有这个必要,[待定]
2. 下面来计算s1这个文件夹里10张图片的平均值:
第一次出错之后发现,想要用某个变量 i 来控制图像自动依次读取,就必须使用 strcat() 这个函数。num2str(i) ,即 number to string,的意思是将循环变量 i 这个数字转变为字符串。接下来再由 strcat() 函数将字符串 i 和后面的‘.bmp’拼接起来,共同组成文件名。
上面这一小片代码的解释:
samples=[]; %Create an EMPTY vector.用于存放10张图片的灰度值信息,每一行代表一张图片
for i=1:10
a=imread(strcat(num2str(i),'.bmp')); %读取第i张图片,存入a
b=a(1:112*92); %将a转换为一维数组(即行向量),存入b
b=double(b); %转换数据类型为double
samples=[samples;b]; %每循环一次,就在原来的sample后面添加一行
end
samplemean=mean(samples); %mean()函数,求输入矩阵的每一列的均值,并返回一个行向量samplemean
figure,imshow(mat2gray(reshape(samplemean,112,92))); %将samplemean这个行向量reshape为112x92的数组,mat2gray=matrix to grayscale image
转换数据类型为double的意义暂不明确,试过删掉这一行,好像并不影响结果。
Matlab的帮助系统很好用,不懂的函数就去Product help里搜,会有解释和举例,很清楚~
3. 下面来计算所有训练样本(放在40个文件夹中的200张图片)的平均值,并对训练集数据进行均值归零:
close all; clear all; clc;
%======================①预处理:将训练集数据中心化======================%
training_set=[]; %创建一个空白数组,用于存放所有训练集图像
for i=1:40
for j=1:5 %只读取每个人的前五张图片作为训练图像
a=imread(strcat('s',num2str(i),'\',num2str(j),'.bmp'));
b=a(1:112*92); %将以上数据转换为1×N的行向量存入b,N=112×92=10304
%提取顺序是从上到下,从左到右
b=double(b); %强制数据类型转换,便于后面的运算操作
training_set=[training_set;b];
%每循环一次,就在原来的traing_set后面添加一行
%traing_set是一个M×N矩阵,每一行代表一张图片。M=40×5=200, N=10304
end
end
Mean=mean(training_set);
%计算平均图片,得到一个1×N的行向量
for i=1:200
X(i,:)=training_set(i,:)-Mean;
%每个图片的数据都减去均值,实现训练集数据的均值归零(中心化)
%减号两边的数据类型必须相同,原始数据的像素灰度值为整数,而平均值是浮点数,所以前面要转换。
end
figure;
%开个图形窗口
subplot(1,2,1),imshow(mat2gray(reshape(Mean,112,92))); title('Mean');
%窗口中,左图显示200张训练集的平均脸
subplot(1,2,2),imshow(mat2gray(reshape(X(1,:),112,92))); title('S1P1-Mean');
%窗口中,右图显示第一个人的第一张图片(记为s1p1)减去平均脸后的效果。
这一步曾经因为没有把 b 的数据类型转换为double而报错了:因为对原始图片数据和平均值数据进行了减法操作。减号两边的数据类型必须相同,原始数据的像素灰度值为整数,而平均值是浮点数。所以前面的代码中必须加上数据类型转换,后面才能相减。
本文介绍主成分分析法(PCA)的基本原理及应用,利用PCA去除图像数据中的冗余信息,提高处理效率。通过MATLAB实现图像数据的均值归零、协方差矩阵计算等步骤。

248

被折叠的 条评论
为什么被折叠?



