PCA具体是如何降维的

来源:互联网 发布:ant build linux命令 编辑:程序博客网 时间:2024/04/27 19:12

一直没有搞清楚,PCA降维到底如何降维,参看了很多文章,如下是比较有用的文章链接:

1.http://apps.hi.baidu.com/share/detail/48483969

2.http://blog.csdn.net/royalvane/article/details/6864271

3.http://blog.sina.com.cn/s/blog_6bc8a3ed0100zy0l.html

4.http://blog.csdn.net/xiazhaoqiang/article/details/5714549

加上自己的理解,算是搞清楚了很多。

由于我是用openCV直接调用函数的,故我想只需要调用cvCalcPCA和cvProjectPCA即可实现降维的目的。

首先调用cvCalcPCA得到平均值矩阵、特征值矩阵、特征向量矩阵

根据第二篇文章里面所说取最大的特征值对应的特征向量,然后将此特征向量转秩,乘以原数据,即为降维

这用到cvProjectPCA
贴源代码如下

#include "cv.h"
#include "highgui.h"
#include <iostream>
#include <fstream>
using namespace std;

const int samples=400;//样本个数
const int  height=19;
 const int  width=20;
const long len= height* width;
int main()
{
   int  *sam_data=new int [samples*height*width];
   char file_sample[samples][100];
   CvMat *data=cvCreateMat(samples,len,CV_32FC1); //样本数据
  
    CvMat *avg=cvCreateMat(1,len,CV_32FC1); //平均值矩阵
   CvMat *eigenvalues=cvCreateMat(1,len,CV_32FC1);]//特征值矩阵1*380
   CvMat *eigenvectors=cvCreateMat(len,len,CV_32FC1);//特征向量矩阵380*380
   CvMat *project_data=cvCreateMat(1,len,CV_32FC1); //测试样本投影到特征空间得到的矩阵1*380
   CvMat *construct_data=cvCreateMat(1,len,CV_32FC1);]//重构后得到一个行向量
   IplImage *src;
   IplImage *resize_src;
   IplImage *img;
   IplImage *construct_img;
  
   resize_src=cvCreateImage(cvSize(height,width),IPL_DEPTH_32F,1);
  img=cvCreateImage(cvSize(height,width),IPL_DEPTH_32F,1);
  construct_img=cvCreateImage(cvSize(height,width),IPL_DEPTH_32F,1);
  
  

    ifstream fin_sample("E:\\samples.txt");
   

  //读入样本
   for (int i_samples=0;i_samples<samples;++i_samples)
     fin_sample.getline(file_sample[i_samples],70 );

 //将所有样本转化为一行存在sam_data中
   for (int i= 0; i< samples; i++){  
         src= cvLoadImage(file_sample[i],CV_LOAD_IMAGE_GRAYSCALE);//src为92*112
       resize_src=cvCreateImage(cvSize(height,width),IPL_DEPTH_8U,1);//resize_src为19*20
        cvResize(src, resize_src);
         cvSmooth(resize_src, resize_src,CV_GAUSSIAN, 3, 0, 0, 0);

      for (int ii= 0; ii< height;ii++) {
          for (int jj= 0; jj< width;jj++) {
              sam_data[i*len+( ii*width)+jj] =((uchar *) (src->imageData+ii*src->widthStep)) [jj];
     
         }
     }
  
    }

  
   cvSetData(data,sam_data,data->step);//得到data(400*380)  每行表示一个样本共400个样本

 

      cvCalcPCA( data, avg,eigenvalues,eigenvectors, CV_PCA_DATA_AS_ROW);

    CvMat*test=cvCreateMat(1,len,CV_32FC1); //测试样本
         //用cvGetRow(data,test,10)从data中取任意一个[color=#0080FF](第10个)
     cvProjectPCA(cvGetRow(data,test,0),avg,eigenvectors,project_data); //将test投影到特征空间

delete []sam_data;


return 0;
}

上述代码中project_data即为所得降维的数据

原创粉丝点击