理论部分可以看斯坦福大学的那份讲义,通俗易懂:http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html

opencv中有PCA这个类,具体的实现可参考:http://www.cnblogs.com/zcftech/archive/2013/04/13/3017411.html

和 http://www.cnblogs.com/tornadomeet/archive/2012/09/06/2673104.html

这当中涉及到了协方差矩阵,包括线代、统计的知识,可参考:http://blog.csdn.net/itplus/article/details/11452743

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp> #include <fstream>
#include <sstream> using namespace cv;
using namespace std; //将给出的图像回归为值域在0~255之间的正常图像
Mat norm_0_255(const Mat& src) {
// 构建返回图像矩阵
Mat dst;
switch (src.channels()) {
case ://根据图像通道情况选择不同的回归函数
cv::normalize(src, dst, , , NORM_MINMAX, CV_8UC1);
break;
case :
cv::normalize(src, dst, , , NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
} // 将一副图像的数据转换为Row Matrix中的一行;这样做是为了跟opencv给出的PCA类的接口对应
//参数中最重要的就是第一个参数,表示的是训练图像样本集合
Mat asRowMatrix(const vector<Mat>& src, int rtype, double alpha = , double beta = ) {
// 样本个数
size_t n = src.size();
// 如果样本为空,返回空矩阵
if (n == )
return Mat();
// 样本的维度
size_t d = src[].total();
// 构建返回矩阵
Mat data(n, d, rtype);
// 将图像数据复制到结果矩阵中
for (int i = ; i < n; i++) {
//如果数据为空,抛出异常
if (src[i].empty()) {
string error_message = format("Image number %d was empty, please check your input data.", i);
CV_Error(CV_StsBadArg, error_message);
}
// 图像数据的维度要是d,保证可以复制到返回矩阵中
if (src[i].total() != d) {
string error_message = format("Wrong number of elements in matrix #%d! Expected %d was %d.", i, d, src[i].total());
CV_Error(CV_StsBadArg, error_message);
}
// 获得返回矩阵中的当前行矩阵:
Mat xi = data.row(i);//引用,改变xi就相当于改变data
// 将一副图像映射到返回矩阵的一行中:
if (src[i].isContinuous()) {
src[i].reshape(, ).convertTo(xi, rtype, alpha, beta);
}
else {
src[i].clone().reshape(, ).convertTo(xi, rtype, alpha, beta);
}
}
return data;
} int main(int argc, const char *argv[]) {
// 训练图像集合
vector<Mat> db;
// 本例中使用的是ORL人脸库,可以自行在网上下载
//将数据读入到集合中 db.push_back(imread("s1/1.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s1/2.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s1/3.pgm", IMREAD_GRAYSCALE)); db.push_back(imread("s2/1.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s2/2.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s2/3.pgm", IMREAD_GRAYSCALE)); db.push_back(imread("s3/1.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s3/2.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s3/3.pgm", IMREAD_GRAYSCALE)); db.push_back(imread("s4/1.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s4/2.pgm", IMREAD_GRAYSCALE));
db.push_back(imread("s4/3.pgm", IMREAD_GRAYSCALE)); // 将训练数据读入到数据集合中,实现PCA类的接口
Mat data = asRowMatrix(db, CV_32FC1); // PCA中设定的主成分的维度,这里我们设置为10维度
int num_components = ; // 构建一份PCA类
PCA pca(data, Mat(), CV_PCA_DATA_AS_ROW, num_components); // 复制PCA方法获得的结果
Mat mean = pca.mean.clone();
Mat eigenvalues = pca.eigenvalues.clone();
Mat eigenvectors = pca.eigenvectors.clone();
namedWindow("avg",);
namedWindow("pc1",);
namedWindow("pc2",);
namedWindow("pc3",); // 平均脸:
imshow("avg", norm_0_255(mean.reshape(, db[].rows))); // 前三个训练人物的特征脸
imshow("pc1", norm_0_255(pca.eigenvectors.row()).reshape(, db[].rows));
imshow("pc2", norm_0_255(pca.eigenvectors.row()).reshape(, db[].rows));
imshow("pc3", norm_0_255(pca.eigenvectors.row()).reshape(, db[].rows)); // Show the images:
waitKey(); // Success!
return ;
}

通过此次实验,学习了怎么使用PCA类,如何将图像数据归一,如何将多幅图像转为一个矩阵

PCA的更多相关文章

  1. 用scikit-learn学习主成分分析(PCA)

    在主成分分析(PCA)原理总结中,我们对主成分分析(以下简称PCA)的原理做了总结,下面我们就总结下如何使用scikit-learn工具来进行PCA降维. 1. scikit-learn PCA类介绍 ...

  2. 主成分分析(PCA)原理总结

    主成分分析(Principal components analysis,以下简称PCA)是最重要的降维方法之一.在数据压缩消除冗余和数据噪音消除等领域都有广泛的应用.一般我们提到降维最容易想到的算法就 ...

  3. 机器学习基础与实践(三)----数据降维之PCA

    写在前面:本来这篇应该是上周四更新,但是上周四写了一篇深度学习的反向传播法的过程,就推迟更新了.本来想参考PRML来写,但是发现里面涉及到比较多的数学知识,写出来可能不好理解,我决定还是用最通俗的方法 ...

  4. 数据降维技术(1)—PCA的数据原理

    PCA(Principal Component Analysis)是一种常用的数据分析方法.PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降 ...

  5. 深度学习笔记——PCA原理与数学推倒详解

    PCA目的:这里举个例子,如果假设我有m个点,{x(1),...,x(m)},那么我要将它们存在我的内存中,或者要对着m个点进行一次机器学习,但是这m个点的维度太大了,如果要进行机器学习的话参数太多, ...

  6. PCA、ZCA白化

    白化是一种重要的预处理过程,其目的就是降低输入数据的冗余性,使得经过白化处理的输入数据具有如下性质:(i)特征之间相关性较低:(ii)所有特征具有相同的方差. 白化又分为PCA白化和ZCA白化,在数据 ...

  7. PCA 协方差矩阵特征向量的计算

    人脸识别中矩阵的维数n>>样本个数m. 计算矩阵A的主成分,根据PCA的原理,就是计算A的协方差矩阵A'A的特征值和特征向量,但是A'A有可能比较大,所以根据A'A的大小,可以计算AA'或 ...

  8. 【统计学习】主成分分析PCA(Princple Component Analysis)从原理到实现

    [引言]--PCA降维的作用 面对海量的.多维(可能有成百上千维)的数据,我们应该如何高效去除某些维度间相关的信息,保留对我们"有用"的信息,这是个问题. PCA给出了我们一种解决 ...

  9. 主成分分析 (PCA) 与其高维度下python实现(简单人脸识别)

    Introduction 主成分分析(Principal Components Analysis)是一种对特征进行降维的方法.由于观测指标间存在相关性,将导致信息的重叠与低效,我们倾向于用少量的.尽可 ...

  10. PCA与LDA的区别与联系

    由于涉及内容较多,这里转载别人的博客: http://blog.csdn.net/sunmenggmail/article/details/8071502 其实主要在于:PCA与LDA的变换矩阵不同, ...

随机推荐

  1. redis学习笔记——(3)

    7.Redis中的set类型       sadd set value:向set中添加元素value. srem set value:删除set中的元素value. spop set:随机返回并删除s ...

  2. C# txt格式记录时间,时间对比,决定是否更新代码记录Demo

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  3. [工具类]文件或文件夹xx已存在,则重命名为xx(n)(2)

    写在前面 最近一直在弄文件传输组件,其中一个功能就是,在接收端接收文件时,如果文件已经存在了,则对其进行文件名+索引的方式进行自动重命名,之前也写个类似的工具类,总感觉代码太冗余,每回头想想,总觉得心 ...

  4. 第六章:javascript:字典

    字典是一种以键-值对应形式存储的数据结构,就像电话薄里的名字和电话号码一样.只要找一个电话,查找名字,名字找到后,电话号码也就找到了.这里的键值是你用来查找的东西,值就是要查的到的结果. javasc ...

  5. 将Image转化为BufferImage

    public class BufferedImageBuilder { private static final int DEFAULT_IMAGE_TYPE = BufferedImage.TYPE ...

  6. 第一次作业---安卓开发工具Android studio发展演变

    Android studio2013年由谷歌推出,用于安卓端的开发,我所使用的版本为2015年5月推出的1.3.2. 1.安装.配置.作为麻瓜的我,刚刚接触Android studio时在安装方面走了 ...

  7. Java编程思想学习(十二) 数组和容器

    一.数组 1).数组的多种初始化方式 下面总结了初始化数组的多种方式,以及如何对指向数组的引用赋值,使其指向另一个数组对象.值得注意的是:对象数组和普通数组的各种操作基本上都是一样的:要说有什么不同的 ...

  8. 统计"1"个数问题

    问题: 给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数. 例如:N=2时 1,2出现了1个 “1” . N=12时 1,2,3,4,5,6,7,8,9,10,11,12.出现了5个“1 ...

  9. 洛谷P1108 低价购买

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  10. Deformity PHP Webshell、Webshell Hidden Learning

    目录 . 引言 . webshell原理介绍 . webshell的常见类型以及变种方法 . webshell的检测原理以及检测工具 . webshell隐藏反检测对抗手段 0. 引言 本文旨在研究W ...