PCA算法的基本原理可以参考:http://www.cnblogs.com/mikewolf2002/p/3429711.html
对一副宽p、高q的二维灰度图,要完整表示该图像,需要m = p*q维的向量空间,比如100*100的灰度图像,它的向量空间为100*100=10000。下图是一个3*3的灰度图和表示它的向量表示:
该向量为行向量,共9维,用变量表示就是[v0, v1, v2, v3, v4, v5, v6, v7, v8],其中v0...v8,的范围都是0-255。
现在的问题是假如我们用1*10000向量,表示100*100的灰度图,是否向量中的10000维对我们同样重要?肯定不是这样的,有些维的值可能对图像更有用,有些维相对来说作用小些。为了节省存储空间,我们需要对10000维的数据进行降维操作,这时就用到了PCA算法,该算法主要就是用来处理降维的,降维后会尽量保留更有意义的维数,它的思想就是对于高维的数据集来说,一部分维数表示大部分有意义的数据。
算法的基本原理:
假设 表示一个特征向量,其中
【注:xi可能也是一个列向量】
2.计算协方差矩阵 S
3.计算S的特征值 和对应的特征向量
,根据线性代数知识我们知道有公式:
4. 对特征值按照大小进行递减排序,特征向量的顺序和特征值是一致的。假设我们只需要保留K个维数(K<n),则我们会选取特征值最大的前K个特征向量,用这K个特征向量,来表示图像,这K个向量就是图像K个主成分分量。
对于被观测的向量,它的K个主成分量可以通过下面公式计算得到:
下面我们在OpenCV中看一个计算PCA的例子:
1.首先读入10副人脸图像,这些图像大小相等,是一个人的各种表情图片。
2.把图片转为1*pq的一维形式,p是图像宽,q是图像高。这时我们的S矩阵就是10行,每行是pq维的向量。
3.然后我们在S上执行PCA算法,设置K=5,求得5个特征向量,这5个特征向量就是我们求得的特征脸,用这5个特征脸图像,可以近似表示之前的十副图像。
}
我们输入的10副图像为:
得到的5副特征脸为:
均值脸为:
程序代码:参照工程FirstOpenCV32