php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 361|回复: 0

利用OpenCV库函数实现PCA(主成成分分析)算法,该算法是...

[复制链接]

3138

主题

3148

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
1
威望
0
积分
7946
贡献
0
注册时间
2021-4-14
最后登录
2024-11-21
在线时间
763 小时
QQ
发表于 2024-1-6 20:27:32 | 显示全部楼层 |阅读模式
  1. /*
  2. * pca.cpp
  3. *
  4. *  Author:
  5. *  Kevin Hughes <kevinhughes27[at]gmail[dot]com>
  6. *
  7. *  Special Thanks to:
  8. *  Philipp Wagner <bytefish[at]gmx[dot]de>
  9. *
  10. * This program demonstrates how to use OpenCV PCA with a
  11. * specified amount of variance to retain. The effect
  12. * is illustrated further by using a trackbar to
  13. * change the value for retained varaince.
  14. *
  15. * The program takes as input a text file with each line
  16. * begin the full path to an image. PCA will be performed
  17. * on this list of images. The author recommends using
  18. * the first 15 faces of the AT&T face data set:
  19. * http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html
  20. *
  21. * so for example your input text file would look like this:
  22. *
  23. *        <path_to_at&t_faces>/orl_faces/s1/1.pgm
  24. *        <path_to_at&t_faces>/orl_faces/s2/1.pgm
  25. *        <path_to_at&t_faces>/orl_faces/s3/1.pgm
  26. *        <path_to_at&t_faces>/orl_faces/s4/1.pgm
  27. *        <path_to_at&t_faces>/orl_faces/s5/1.pgm
  28. *        <path_to_at&t_faces>/orl_faces/s6/1.pgm
  29. *        <path_to_at&t_faces>/orl_faces/s7/1.pgm
  30. *        <path_to_at&t_faces>/orl_faces/s8/1.pgm
  31. *        <path_to_at&t_faces>/orl_faces/s9/1.pgm
  32. *        <path_to_at&t_faces>/orl_faces/s10/1.pgm
  33. *        <path_to_at&t_faces>/orl_faces/s11/1.pgm
  34. *        <path_to_at&t_faces>/orl_faces/s12/1.pgm
  35. *        <path_to_at&t_faces>/orl_faces/s13/1.pgm
  36. *        <path_to_at&t_faces>/orl_faces/s14/1.pgm
  37. *        <path_to_at&t_faces>/orl_faces/s15/1.pgm
  38. *
  39. */

  40. #include <iostream>
  41. #include <fstream>
  42. #include <sstream>

  43. #include <opencv2/core/core.hpp>
  44. #include <opencv2/highgui/highgui.hpp>

  45. using namespace cv;
  46. using namespace std;

  47. ///////////////////////
  48. // Functions
  49. static void read_imgList(const string& filename, vector<Mat>& images)
  50. {
  51.     std::ifstream file(filename.c_str(), ifstream::in);

  52.     if (!file)
  53.         {
  54.         string error_message = "No valid input file was given, please check the given filename.";
  55.         CV_Error(CV_StsBadArg, error_message);
  56.     }

  57.     string line;
  58.     while (getline(file, line))
  59.         {
  60.         images.push_back(imread(line, 0));
  61.     }
  62. }

  63. static  Mat formatImagesForPCA(const vector<Mat> &data)
  64. {
  65.     Mat dst( static_cast<int>(data.size()), data[0].rows * data[0].cols, CV_32F ); //static_cast:ǿ  ת  

  66.     for(unsigned int i = 0; i < data.size(); i++)
  67.     {
  68.         Mat image_row = data[i].clone().reshape(1,1);
  69.         Mat row_i = dst.row(i);
  70.         image_row.convertTo(row_i,CV_32F);
  71.     }
  72.     return dst;
  73. }

  74. static Mat toGrayscale(InputArray _src)
  75. {
  76.     Mat src = _src.getMat();
  77.     // only allow one channel
  78.     if(src.channels() != 1)
  79.         {
  80.         CV_Error(CV_StsBadArg, "Only Matrices with one channel are supported");
  81.     }
  82.     // create and return normalized image
  83.     Mat dst;
  84.     cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
  85.     return dst;
  86. }

  87. struct params
  88. {
  89.     Mat data;
  90.     int ch;
  91.     int rows;
  92.     PCA pca;
  93.     string winName;
  94. };

  95. static void onTrackbar(int pos, void* ptr)
  96. {
  97.     cout << "Retained Variance = " << pos << "%   ";
  98.     cout << "re-calculating PCA..." << std::flush;

  99.     double var = pos / 100.0;

  100.     struct params *p = (struct params *)ptr;

  101.     p->pca = PCA(p->data, cv::Mat(), CV_PCA_DATA_AS_ROW, var);

  102.     Mat point = p->pca.project(p->data.row(0));
  103.     Mat reconstruction = p->pca.backProject(point);
  104.     reconstruction = reconstruction.reshape(p->ch, p->rows);
  105.     reconstruction = toGrayscale(reconstruction);

  106.     imshow(p->winName, reconstruction);
  107.     cout << "done!   # of principal components: " << p->pca.eigenvectors.rows << endl;
  108. }


  109. ///////////////////////
  110. // Main
  111. int main(int argc, char** argv)
  112. {
  113.     if (argc != 2)
  114.         {
  115.         cout << "usage: " << argv[0] << " <image_list.txt>" << endl;
  116.         exit(1);
  117.     }

  118.     // Get the path to your CSV.
  119.     string imgList = string(argv[1]);

  120.     // vector to hold the images
  121.     vector<Mat> images;

  122.     // Read in the data. This can fail if not valid
  123.     try
  124.         {
  125.         read_imgList(imgList, images);
  126.     }
  127.         catch (cv::Exception& e)
  128.         {
  129.         cerr << "Error opening file "" << imgList << "". Reason: " << e.msg << endl;
  130.         exit(1);
  131.     }

  132.     // Quit if there are not enough images for this demo.
  133.     if(images.size() <= 1)
  134.         {
  135.         string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
  136.         CV_Error(CV_StsError, error_message);
  137.     }

  138.     // Reshape and stack images into a rowMatrix
  139.     Mat data = formatImagesForPCA(images);

  140.     // perform PCA
  141.     PCA pca(data, cv::Mat(), CV_PCA_DATA_AS_ROW, 0.95); // trackbar is initially set here, also this is a common value for retainedVariance

  142.     // Demonstration of the effect of retainedVariance on the first image
  143.     Mat point = pca.project(data.row(0)); // project into the eigenspace, thus the image becomes a "point"
  144.     Mat reconstruction = pca.backProject(point); // re-create the image from the "point"
  145.     reconstruction = reconstruction.reshape(images[0].channels(), images[0].rows); // reshape from a row vector into image shape
  146.     reconstruction = toGrayscale(reconstruction); // re-scale for displaying purposes

  147.     // init highgui window
  148.     string winName = "Reconstruction | press 'q' to quit";
  149.     namedWindow(winName, WINDOW_NORMAL);

  150.     // params struct to pass to the trackbar handler
  151.     params p;
  152.     p.data = data;
  153.     p.ch = images[0].channels();
  154.     p.rows = images[0].rows;
  155.     p.pca = pca;
  156.     p.winName = winName;

  157.     // create the tracbar
  158.     int pos = 95;
  159.     createTrackbar("Retained Variance (%)", winName, &pos, 100, onTrackbar, (void*)&p);

  160.     // display until user presses q
  161.     imshow(winName, reconstruction);

  162.     int key = 0;
  163.     while(key != 'q')
  164.         key = waitKey();

  165.    return 0;
  166. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|php中文网 | cnphp.com ( 赣ICP备2021002321号-2 )

GMT+8, 2024-11-21 22:15 , Processed in 0.982890 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

申明:本站所有资源皆搜集自网络,相关版权归版权持有人所有,如有侵权,请电邮(fiorkn@foxmail.com)告之,本站会尽快删除。

快速回复 返回顶部 返回列表