使用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;
}
发布了59 篇原创文章 · 获赞 57 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/xiakejiang/article/details/104915312
今日推荐