理论部分可以看斯坦福大学的那份讲义,通俗易懂: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类,如何将图像数据归一,如何将多幅图像转为一个矩阵

最新文章

  1. 轻量的、可自定义 CSS 的 Lightbox 相册插件
  2. Ubuntu12.04安装YouCompleteMe插件
  3. Windows下codeblocks的安装与配置
  4. codeforces -- 283A
  5. 记“debug alipay”一事
  6. MySQL---连接器(python如何操作数据库媒介,基于python语言)
  7. Android关于AutoService、Javapoet讲解
  8. 重载重写重定义-易混淆概念-C++编译器处理方式
  9. django中models field详解
  10. java后端的知识学习
  11. Nginx (LNMP+https)
  12. php 7 event 安装
  13. MongoDB 系列文章
  14. Functions: C++&#39;s Programming Modules
  15. 分布式实时日志系统(四) 环境搭建之centos 6.4下hbase 1.0.1 分布式集群搭建
  16. jQuery扩展插件以及正则相关函数练习
  17. PS改变图像颜色
  18. 从Oracle官网学习oracle数据库和java
  19. Python学习 :网络通信要素
  20. 【BZOJ1566】【NOI2009】管道取珠(动态规划)

热门文章

  1. ModernUI教程:使用预定义的页面布局
  2. excel导入数据库
  3. java和linux的编码
  4. 关于软工项目beta版本
  5. at org.apache.catalina.loader.WebappClassLoader.loadClass问题处理
  6. MVC4学习笔记(一)
  7. [转]DBA,SYSDBA,SYSOPER三者的区别
  8. UVA1220Party at Hali-Bula(树的最大独立集 + 唯一性判断)
  9. Asp.Net MVC3 简单入门详解过滤器Filter
  10. 使用Jquery+EasyUI 进行框架项目开发案例讲解之五 模块(菜单)管理源码分享