openCV学习笔记(十六) —— 人脸识别 —— 程序 —— PCA特征脸Eigenfaces、重建人脸

版权声明:若转载,请注明链接地址! https://blog.csdn.net/guoyunfei123/article/details/81382351

此程序主要来源于F:\personal\data\openCV\opencv_contrib_3.4.1\modules\face\samples\facerec_eigenfaces.cpp

流程

  1. 读人脸数据文件
  2. 创建特征脸识别与训练
  3. 识别人脸
  4. 输出中间平均脸、特征脸、重建结果 

相关图示 

程序 


/*
	此程序主要来源于F:\personal\data\openCV\opencv_contrib_3.4.1\modules\face\samples\facerec_eigenfaces.cpp
*/
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>

//#include <fstream>
//#include <iostream>

using namespace std;
using namespace cv;
using namespace cv::face;

Mat normal(Mat& src, Mat& dst)
{
	if (src.channels() == 1)
	{
		normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
	}
	else
	{
		normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
	}

	return dst;
}

void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';')
{
	std::ifstream file(filename.c_str(), ifstream::in);
	if (!file) {
		string error_message = "No valid input file was given, please check the given filename.";
		CV_Error(Error::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()
{
	string filename = ".\\face_recg\\face\\at.txt";

	vector<Mat> images;
	vector<int> labels;

	//从文件中读取图像保存到向量中
	try {
		read_csv(filename, images, labels);
	}
	catch (Exception& e)
	{
		cerr << "Error opening file \n" << filename << "\". Reason: " << e.msg << endl;
		exit(1);
	}

	if (images.size() <= 1)
	{
		cerr << "图像太少,请至少添加两个图片!" << endl;
		exit(1);
	}

	//从第一个图像获取高度,在后面的代码里面需要用到它来重塑原来的图片大小
	int height = images[0].rows;
	int width = images[0].cols;
	printf("height: %d, width: %d\n", height, width);

	//最后一个人为测试样本
	Mat testSample = images[images.size() - 1];
	int testLabel = labels[labels.size() - 1];
	images.pop_back();
	labels.pop_back();

	//训练
	Ptr<EigenFaceRecognizer> model = EigenFaceRecognizer::create();
	model->train(images, labels);

	//识别
	int predictedLabel = model->predict(testSample);
	printf("actual label: %d, predict label: %d\n", testLabel, predictedLabel);

	//获得特征值,特征向量,均值,平均脸
	Mat eigenValues = model->getEigenValues();
	Mat eigenVector = model->getEigenVectors();
	Mat mean = model->getMean();
	Mat meanFace = mean.reshape(1, height);

	Mat dst;
	dst = normal(meanFace, dst);
	imshow("MeanFace", dst);

	//特征脸
	for (int i = 0; i < min(10, eigenVector.cols); i++)
	{
		Mat ev = eigenVector.col(i).clone();
		Mat eigenFace = ev.reshape(1, height);

		Mat grayScale;
		grayScale = normal(eigenFace, grayScale);

		Mat colorFace;
		applyColorMap(grayScale, colorFace, COLORMAP_BONE);

		imshow(format("eigenFace_%d", i), colorFace);
	}

	//重建人脸
	for (int i = min(10, eigenVector.cols); i < min(300, eigenVector.cols); i += 15)
	{
		Mat evs = Mat(eigenVector, Range::all(), Range(0, i));
		Mat projection = LDA::subspaceProject(evs, mean, images[0].reshape(1, 1));
		Mat reconstruction = LDA::subspaceReconstruct(evs, mean, projection);

		Mat result = reconstruction.reshape(1, height);
		reconstruction = normal(result, reconstruction);
		imshow(format("reco_face_%d", i), reconstruction);
	}

	waitKey(0);
	destroyAllWindows();

	return 0;
}

 

展开阅读全文

没有更多推荐了,返回首页