使用opencv的PCA主成分分析示例

opencv pca主成分分析使用樣例:

 

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>

using namespace cv;
using namespace std;

#define DIMENTIONS			512			// 特徵向量維數
#define SAMPLE_NUM			16204		// 樣本個數
#define PCA_DIMS			64			// PCA降維特徵值數量
#define PCA_MEAN			"mean"
#define PCA_EIGEN_VECTOR	"eigen_vector"

cv::Mat read_csv(const char *filepath, cv::Size img_size, int img_type);

int main()
{
	// 1 讀特徵向量
	std::string lfwFeature = "./imgfeatures.csv";
	cv::Mat SampleSet = read_csv(lfwFeature.c_str(), cv::Size(DIMENTIONS, SAMPLE_NUM), CV_32FC1);

	// 2 Training
	PCA *pca = new PCA(SampleSet, Mat(), CV_PCA_DATA_AS_ROW);
	// 特徵值求和
	float sum_eigVal = 0.0f;
	for (int i = 0; i < DIMENTIONS; ++i)
	{
		sum_eigVal += pca->eigenvalues.at<float>(i, 0);
	}
	
	//
	Mat eigenvetors_d;
	float save_eigenVal = 0.0f;
	eigenvetors_d.create(PCA_DIMS, DIMENTIONS, CV_32FC1);			// eigen values of decreased dimension
	for (int i = 0; i < PCA_DIMS; ++i)
	{
		pca->eigenvectors.row(i).copyTo(eigenvetors_d.row(i));		// 特徵向量保存到eigenvetors_d
		save_eigenVal += pca->eigenvalues.at<float>(i, 0);
	}
	printf("prePCA_DIMS %.4f percentage\n", save_eigenVal*1.0 / sum_eigVal);
	//cout << "eigenvectors" << endl << eigenvetors_d << endl;
	FileStorage fs_w("config.xml", FileStorage::WRITE);				// write mean and eigenvalues into xml file
	fs_w << PCA_MEAN << pca->mean;
	fs_w << PCA_EIGEN_VECTOR << eigenvetors_d;
	fs_w.release();
	
	//Encoding
	PCA *pca_encoding = new PCA();
	//Mat input(1, DIMENTIONS, CV_32FC1);//Test input
	//for (int j = 0; j < DIMENTIONS; ++j)
	//{
	//	input.at<float>(0, j) = rand() % 100;
	//}
	//FileStorage fs_r("config.xml", FileStorage::READ);
	//fs_r[PCA_MEAN] >> pca_encoding->mean;
	//fs_r[PCA_EIGEN_VECTOR] >> pca_encoding->eigenvectors;
	//fs_r.release();
	//
	//Mat output_encode(1, pca_encoding->eigenvectors.rows, CV_32FC1);	// 經pca變換後的特徵向量
	//pca_encoding->project(input, output_encode);

	//delete pca;
	delete pca_encoding;
	
	system("pause");
	return 0;
}


cv::Mat read_csv(const char *filepath, cv::Size img_size, int img_type)
{
	cv::Mat image;
	image.create(img_size, img_type);
	string pixel;

	std::ifstream file(filepath, std::ifstream::in);
	if (!file)
		std::cout << "CSV read fail" << std::endl;

	int nl = image.rows;  // number of lines   
	int nc = image.cols;  // number of columns   
	int eolElem = image.cols - 1;		//每行最後一個元素的下標
	int elemCount = 0;
	if (image.isContinuous())
	{
		nc = nc*nl;    // then no padded pixels   
		nl = 1;		   // it is now a 1D array   
	}
	for (int i = 0; i < nl; i++)
	{
		float* data = (float*)image.ptr<ushort>(i);
		for (int j = 0; j < nc; j++)
		{
			if (elemCount == eolElem)
			{
				getline(file, pixel, '\n');				//任意地讀入,直到讀到delim字符 '\n',delim字符不會被放入buffer中
				data[j] = (float)atof(pixel.c_str());	//將字符串str轉換成一個雙精度數值並返回結果
				elemCount = 0;							//計數器置零
			}
			else
			{
				getline(file, pixel, ',');				//任意地讀入,直到讀到delim字符 ','delim字符不會被放入buffer中
				data[j] = (float)atof(pixel.c_str());	//將字符串str轉換成一個雙精度數值並返回結果
				elemCount++;
			}
		}
	}
	file.close();
	return image;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章