OpenCV实现人脸识别——EigenFace特征脸法

 

从OpenCV2.4开始,加入新的类FaceRecognizer,可以用它方便的进行人脸识别实验。

目前支持的算法有

       Eigenface特征脸   createEigenFaceRecognizer()

       Fisherface             createFisherFaceRecognizer()

      Local Binary Patterns Histograms局部二值直方图    createLBPHFaceRecognizer()

 

这篇文章就特征脸方法进行了实验,代码是根据OpenCV2.4.3里面的samples/cpp文件的facerec_demo.cpp例程所改写的,人脸库用的是ORL人脸数据库,使用CSV文件来记录人脸库中图片所在的目录和标签。

算法描述:

2  表示一个随机特征,其中3 .

  1. 计算均值向量 4
                             5


  1. 计算协方差矩阵 S
                                6


  1. 计算的特征值 7   和对应的特征向量 8             9
  1. 对特征值进行递减排序,特征向量和他的顺序一致。K个主成分也就是K和最大的特征值对应的特征向量。

          x的K个主成分:

10

其中11  .

PCA基的重构:

12

其中13 .

然后特征脸通过下面的方式进行人脸识别:

          1.把所有的训练数据投影大PCA子空间

          2.把待识别的图像投影到PCA子空间

              3.找到训练数据投影后的想来那个和待识别图像投影后的向量最近的那个。

源代码:

 

#if 1

#include 
#include 
#include 

#include 
#include 
#include 

using namespace std;
using namespace cv;

static  Mat norm_0_255(cv::InputArray _src)
{
	Mat src = _src.getMat();
	Mat dst;

	switch(src.channels())
	{
	case 1:
		cv::normalize(_src, dst, 0, 255, cv::NORM_MINMAX, CV_8UC1);
		break;
	case 3:
		cv::normalize(_src, dst, 0, 255, cv::NORM_MINMAX, CV_8UC3);
		break;
	default:
		src.copyTo(dst);
		break;
	}

	return dst;
}

static void read_csv(const string &filename, vector &images, vector &labels, char separator = ';')
{
	std::ifstream file(filename.c_str(), ifstream::in);
	if(!file)
	{
		string error_message = "No valid input file was given.";
		CV_Error(CV_StsBadArg, error_message);
	}

	string line, path, classlabel;
	while(getline(file, line))
	{
		stringstream liness(line);
		getline(liness, path, separator);  //遇到分号就结束
		getline(liness, classlabel);     //继续从分号后面开始,遇到换行结束
		if(!path.empty() && !classlabel.empty())
		{
			images.push_back(imread(path, 0));
			labels.push_back(atoi(classlabel.c_str()));
		}
	}
}

int main(int argc, char *argv[])
{
	string output_folder;
	output_folder = string("D:\\ORL\\result");

	//读取你的CSV文件路径
	string fn_csv = string("D:\\ORL\\to\\at.txt");

	//两个容器来存放图像数据和对应的标签
	vector images;
	vector labels;

	try
	{
		read_csv(fn_csv, images, labels);	
	}
	catch(cv::Exception &e)
	{
		cerr<<"Error opening file "< model = cv::createEigenFaceRecognizer();
	model->train(images, labels);

	/*
	* 下面对测试图像进行预测,predictedLabel 是预测标签结果
	*/
	int predictedLabel = model->predict(testSample);

	string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
	cout<getMat("eigenvalues");
	//获取特征向量
	Mat W = model->getMat("eigenvectors");

	//得到训练图像的均值向量
	Mat mean = model->getMat("mean");

	imshow("mean", norm_0_255(mean.reshape(1, images[0].rows)));
	cv::imwrite(format("%s/mean.png", output_folder.c_str()), norm_0_255(mean.reshape(1, images[0].rows)));

	//实现并保存特征脸
	for(int i=0; i (i));
		cout<


 

 

你可能感兴趣的:(OpenCv)