1. LDA类的声明文件在core.hpp中,可以通过包含opencv2/opencv.hpp来包含。
/**
@brief Linear Discriminant Analysis
@todo document this class
*/
class CV_EXPORTS LDA
{
public:
/** @brief constructor
Initializes a LDA with num_components (default 0).
*/
explicit LDA(int num_components = 0);
/** 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);
/** 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 (row aligned) and labels.
*/
void compute(InputArrayOfArrays src, InputArray labels);
/** Projects samples into the LDA subspace.
src may be one or more row aligned samples.
*/
Mat project(InputArray src);
/** Reconstructs projections from the LDA subspace.
src may be one or more row aligned projections.
*/
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; }
static Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
static Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
protected:
bool _dataAsRow; // unused, but needed for 3.0 ABI compatibility.
int _num_components;
Mat _eigenvectors;
Mat _eigenvalues;
void lda(InputArrayOfArrays src, InputArray labels);
};
2. 使用举例
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
//Opencv 3.X 系列的LDA类在core.hpp中,而opencv.hpp中有了对core.hpp的包含
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(void)
{
//样本数据
double sampledata[7][2]={{2.95,6.63},{2.53,7.79},{3.57,5.65},{3.16,5.47},{2.58,4.46},{2.16,6.22},{3.27,3.52}};
Mat dataMat=Mat(7,2,CV_64FC1,sampledata);
//样本标签
int dataLable[7]={0,0,0,0,1,1,1};
Mat labelMat=Mat(7,1,CV_32SC1,dataLable);
//LDA计算-两种方法
/*
第一种直接使用带参数的构造函数LDA (InputArrayOfArrays src, InputArray labels, int num_components=0),实际上内部也是调用了成员函数void compute (InputArrayOfArrays src, InputArray labels)来计算特征值特特征向量
第二种方法就是构造函数LDA (int num_components=0),然后调用成员函数compute函数
*/
LDA lda=LDA();
lda.compute(dataMat,labelMat);
//输出特征向量-所求的子空间
Mat eivector=lda.eigenvectors();
cout<<"rows:"<<eivector.rows<<endl;
cout<<"cols:"<<eivector.cols<<endl;
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;
}
//输出特征值
cout<<"----------------------------"<<endl;
Mat eigenValue=lda.eigenvalues();
cout<<"rows:"<<eigenValue.rows<<endl;
cout<<"cols:"<<eigenValue.cols<<endl;
for(int i=0;i<eigenValue.rows;i++)
{
for(int j=0;j<eigenValue.cols;j++)
{
cout<<eigenValue.ptr<double>(i)[j]<<" ";
}
cout<<endl;
}
//投影-将样本投影到新的空间
cout<<"----------------------------"<<endl;
Mat dataSub =lda.project(dataMat);
cout<<"rows:"<<dataSub.rows<<endl;
cout<<"cols:"<<dataSub.cols<<endl;
for(int i=0;i<dataSub.rows;i++)
{
for(int j=0;j<dataSub.cols;j++)
{
cout<<dataSub.ptr<double>(i)[j]<<" ";
}
cout<<endl;
}
system("pause");
return 0;
}