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;
}

posted @ 2016-03-15 16:48  zfyouxi  阅读(669)  评论(0编辑  收藏  举报