OpenCV LDA(Linnear Discriminant analysis)类的使用---OpenCV LDA演示样例
1、OpenCV中LDA类的声明
//contrib.hpp class CV_EXPORTS LDA { public: // Initializes a LDA with num_components (default 0) and specifies how // samples are aligned (default dataAsRow=true). LDA(int num_components = 0) : _num_components(num_components) {}; // Initializes and performs a Discriminant Analysis with Fisher's // Optimization Criterion on given data in src and corresponding labels // in labels. If 0 (or less) number of components are given, they are // automatically determined for given data in computation. LDA(const Mat& src, vector<int> labels, int num_components = 0) : _num_components(num_components) { this->compute(src, labels); //! compute eigenvectors and eigenvalues } // Initializes and performs a Discriminant Analysis with Fisher's // Optimization Criterion on given data in src and corresponding labels // in labels. If 0 (or less) number of components are given, they are // automatically determined for given data in computation. LDA(InputArrayOfArrays src, InputArray labels, int num_components = 0) : _num_components(num_components) { this->compute(src, labels); //! compute eigenvectors and eigenvalues } // Serializes this object to a given filename. void save(const string& filename) const; // Deserializes this object from a given filename. void load(const string& filename); // Serializes this object to a given cv::FileStorage. void save(FileStorage& fs) const; // Deserializes this object from a given cv::FileStorage. void load(const FileStorage& node); // Destructor. ~LDA() {} //! Compute the discriminants for data in src and labels. void compute(InputArrayOfArrays src, InputArray labels); // Projects samples into the LDA subspace. Mat project(InputArray src); // Reconstructs projections from the LDA subspace. Mat reconstruct(InputArray src); // Returns the eigenvectors of this LDA. Mat eigenvectors() const { return _eigenvectors; }; // Returns the eigenvalues of this LDA. Mat eigenvalues() const { return _eigenvalues; } protected: bool _dataAsRow; int _num_components; Mat _eigenvectors; Mat _eigenvalues; void lda(InputArrayOfArrays src, InputArray labels); };
2、演示样例
// LDA.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <contrib\contrib.hpp> #include <cxcore.hpp> using namespace cv; using namespace std; int main(void) { //sampledata double sampledata[6][2]={{0,1},{0,2},{2,4},{8,0},{8,2},{9,4}}; Mat mat=Mat(6,2,CV_64FC1,sampledata); //labels vector<int>labels; for(int i=0;i<mat.rows;i++) { if(i<mat.rows/2) { labels.push_back(0); } else { labels.push_back(1); } } //do LDA LDA lda=LDA(mat,labels); //get the eigenvector Mat eivector=lda.eigenvectors().clone(); cout<<"The eigenvector is:"<<endl; for(int i=0;i<eivector.rows;i++) { for(int j=0;j<eivector.cols;j++) { cout<<eivector.ptr<double>(i)[j]<<" "; } cout<<endl; } //针对两类分类问题,计算两个数据集的中心 int classNum=2; vector<Mat> classmean(classNum); vector<int> setNum(classNum); for(int i=0;i<classNum;i++) { classmean[i]=Mat::zeros(1,mat.cols,mat.type()); setNum[i]=0; } Mat instance; for(int i=0;i<mat.rows;i++) { instance=mat.row(i); if(labels[i]==0) { add(classmean[0], instance, classmean[0]); setNum[0]++; } else if(labels[i]==1) { add(classmean[1], instance, classmean[1]); setNum[1]++; } else {} } for(int i=0;i<classNum;i++) { classmean[i].convertTo(classmean[i],CV_64FC1,1.0/static_cast<double>(setNum[i])); } vector<Mat> cluster(classNum); for(int i=0;i<classNum;i++) { cluster[i]=Mat::zeros(1,1,mat.type()); multiply(eivector.t(),classmean[i],cluster[i]); } cout<<"The project cluster center is:"<<endl; for(int i=0;i<classNum;i++) { cout<<cluster[i].at<double>(0)<<endl; } system("pause"); return 0; }