opencv PCA算法

#include <iostream>
#include <opencv2/opencv.hpp>
#include <sstream>
using namespace std;
using namespace  cv;
//PCA算法的实现和总结
int main()
{
	//文件路名的前缀
	string filename = "C:/Users/Administrator/Desktop/标准测试图片/CMU_PIE_Face/CMU_PIE_Face/Pose07_64x64_files/";
	//选择20幅影像  d=20
	vector<Mat> Images;//影像的集合
	for (int i = 11; i <= 220;i+=11)//这里仅仅是寻找影像的文件名,因为是以数字命名的,所以有这样的表达式,可以跳过
	{
		string name("");
		ostringstream os;
		os << i;
		name = os.str() + ".jpg";
		Mat temp = imread(filename+name, IMREAD_GRAYSCALE);//以灰度影像的方式进行读取
		if (temp.empty())
		{
			continue;//如果读取失败,那么就继续下一副进行读取
		}
		//temp.convertTo(temp, CV_32FC1);//转换为浮点数
		Images.push_back(temp);
	}
	//将影像合并成一幅影像,影像的大小为M*N,将这幅影像合并成一行数据 读取影像是64*64=4096
	if (Images.empty())
	{
		return -1;//影像读取全部失败了
	}
	Mat BigImage = Mat(Images.size(), Images[0].cols*Images[0].rows, CV_32FC1);//大影像的大小为20 * 4096
	//填充这一幅大影像
	for (size_t i = 0; i < Images.size();++i)
	{
		//将每一幅影像的数据合并到大影像的行中
		//Mat xi = BigImage.row(i);
		Images[i].reshape(1, 1).convertTo(BigImage.row(i), CV_32FC1);
	}
	//现在可以进行PCA处理了
	PCA pca(BigImage, noArray(), PCA::DATA_AS_ROW);//PCA 构造函数
	Mat EigenValue = pca.eigenvalues.clone();//大小是20*1
	//统计特征能量大于95%的成分
	double Sum = 0;
	for (size_t i = 0; i < Images.size();++i)
	{
		Sum += EigenValue.at<float>(i);
	}
	double Radio = 0.95;
	int index = 0;
	double Add = 0;
	while (Add/Sum<0.95)
	{
		Add += EigenValue.at<float>(index);
		++index;
	}
	//重新进行PCA分析
	PCA pca1(BigImage, noArray(), PCA::DATA_AS_ROW,index);//PCA 构造函数----其中index =11  占有95的能量
	//上述的函数PCA的构造函数中,也有另一个构造函数,最后一个参数是double类型,占有的比率,这里写出的原因的,是想看看
	//一般特征值在前几个占的比率比较大
	FileStorage fs;//将训练的PCA结果保存下来,以方便以后使用
	fs.open("PCA.xml", FileStorage::WRITE);
	if (fs.isOpened())
	{
		pca1.write(fs);
		fs.release();
	}
	//特征向量大小为20*4096
	Mat mean = pca1.mean.clone().reshape(0,Images[0].rows);//均值影像
	//归一化处理
	Mat dst;
	normalize(mean, dst, 0, 255, NORM_MINMAX,CV_8UC1);//这个在不同类型的时候,不支持in-place操作
	imshow("mean", dst);
	Mat FirstImage = pca1.project(BigImage.row(0));//将第一幅原始影像投影到PCA中   投影之后的维度为1*11 (11是上述提取的最大主成分量)
	Mat FirstResult = pca1.backProject(FirstImage);//反向投影,是为了看看影像的结果
	Mat result=FirstResult.reshape(0, Images[0].rows);
	Mat dst1;
	normalize(result, dst1, 0, 255, NORM_MINMAX,CV_8UC1);
	imshow("tile", dst1);
	//查看第一个特征量-主特征脸
	Mat EigenFace = pca.eigenvectors.row(0).reshape(0, Images[0].rows);
	Mat dst2;
	normalize(EigenFace, dst2, 0, 255, NORM_MINMAX, CV_8UC1);
	imshow("Eigen0", dst2);
	waitKey(0);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值