我是靠谱客的博主 无聊心情,最近开发中收集的这篇文章主要介绍基于PCA算法的人脸识别制作自己的样本实现识别自己的人脸1.图像的采集及预处理2.csv文件的生成3.训练模型4.人脸识别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 之前的刚学习OpenCV的时候,对人脸识别感兴趣,觉得能够实现识别自己的脸感觉很棒。通过一段时间的学习之后,发现其实并不难。网上较多的都是PCA算法的人脸识别,这是相对来说比较老的算法了,多数的东西OpenCV都是自带的,借助该算法来学习也比较方便。

下面来具体说一下从制作样本到训练样本,再到最后调用摄像头识别自己人脸的整个过程。

1.图像的采集及预处理

要想识别指定的人,则需要将被识别人的照片做成数据集,也就是训练模型。传统获得照片的途径就是通过手机拍照、自拍。一个人需要20张不同角度和表情的照片,要实现几个人的训练模型,手机拍照显得比较麻烦,而且效果不佳,倒不如通过电脑摄像头实现。通过查阅资料,利用OpenCV写了一个拍照的小程序,并将图片提前进行了灰度处理以及中值滤波处理。然后将图片缩小到指定的120*120的大小,拍出来的照片能达到样本级的水平,省去了很多二次处理的过程。

代码如下:

#include <opencv2opencv.hpp>

using namespace cv;

int main()
{
	VideoCapture cap(0);
	Mat frame;
	int i=0;
	while (1)  
    {  
            char key = waitKey(100);  
            cap >> frame;
			imshow("frame", frame);
			Mat out;
			Mat out1;
			Mat out2;
			cvtColor(frame, out1, CV_BGR2GRAY);//灰度化
			medianBlur(out1,out,7);//中值滤波
			 resize(out, out2, Size(120, 120));//尺寸缩减
            imshow("out", out2);
            string filename = format("D:\pic\pic%d.jpg", i);//存入文件路径  
            switch (key)  
            {  
            case'p':  //按'P'拍照
                i++;  
                imwrite(filename, out2);  
                imshow("photo", out2);  
                waitKey(500);  
                destroyWindow("photo");
                break; 	
            default:  
                break;  
            }  
	}
}

这样得到的图片已经是经过处理之后的,可以当做样本使用。效果如图所示:

这样初步的样本就制作好了。

2.csv文件的生成

当我们写人脸模型的训练程序的时候,我们需要读取人脸和人脸对应的标签。直接在数据库中读取显然是低效的。所以我们用csv文件读取。csv文件中包含两方面的内容,一是每一张图片的位置所在,二是每一个人脸对应的标签,也就是每一个人编号。这个at.txt就是我们需要的csv文件。如图所示:

在图中,前面所显示的路径是图片的位置,后面的数字是该图片所对应人的的标签。如果你用于学习,只制作几个人的样本集来试验的话,可以直接手动创建复制路径,工作量不大,三个人的几分钟搞定。如果你是要做多个人的可以利用OpenCV自带的脚本自动生成,(可以网上搜一下,我这里忘了)最后就能得到既有路径又有标签的csv文件。

3.训练模型

数据集和csv文件都已经准备好了,接下来就可以进行模型训练。首先,需要先将之前的图片和标签提取出来,这个时候就需要用到at.txt。使用csv文件去读图像和标签,主要会用到stringstream和getline方法。Stringstream主要是将一个字符串分割,在将个别内容分开输出;getline则是从输入流中读入字符存到指定的地方。通过stringstream和getline两个方法,将csv文件中的图像和标签分别存到images和labels连个容器中。

注意的是,这里的at.txt文件内容及是将CSV文件的内容复制过来,需要放入到训练模型代码的文件夹中,否则加载不到会报错。

训练模型代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>

using namespace cv;
using namespace std;

static Mat norm_0_255(InputArray _src) {
	Mat src = _src.getMat();
	// 创建和返回一个归一化后的图像矩阵:
	Mat dst;
	switch (src.channels()) {
	case1:
		cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
		break;
	case3:
		cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
		break;
	default:
		src.copyTo(dst);
		break;
	}
	return dst;
}

//使用CSV文件去读图像和标签,主要使用stringstream和getline方法
static 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(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() 
{

	//读取你的CSV文件路径.
	//string fn_csv = string(argv[1]);
	string fn_csv = "at.txt";

	// 2个容器来存放图像数据和对应的标签
	vector<Mat> images;
	vector<int> labels;
	// 读取数据. 如果文件不合法就会出错
	// 输入的文件名已经有了.
	try
	{
		read_csv(fn_csv, images, labels);
	}
	catch (cv::Exception& e)
	{
		cerr << "Error opening file "" << fn_csv << "". Reason: " << e.msg << endl;
		// 文件有问题,我们啥也做不了了,退出了
		exit(1);
	}
	// 如果没有读取到足够图片,也退出.
	if (images.size() <= 1) {
		string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
		CV_Error(CV_StsError, error_message);
	}

	// 下面的几行代码仅仅是从你的数据集中移除最后一张图片
	//[gm:自然这里需要根据自己的需要修改,他这里简化了很多问题]

	// 下面几行创建了一个特征脸模型用于人脸识别,
	// 通过CSV文件读取的图像和标签训练它。
	// T这里是一个完整的PCA变换
	//如果你只想保留10个主成分,使用如下代码
	//      cv::createEigenFaceRecognizer(10);
	//
	// 如果你还希望使用置信度阈值来初始化,使用以下语句:
	//      cv::createEigenFaceRecognizer(10, 123.0);
	//
	// 如果你使用所有特征并且使用一个阈值,使用以下语句:
	//      cv::createEigenFaceRecognizer(0, 123.0);
	
	Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
	model->train(images, labels);
	model->save("MyFacePCAModel.xml");

	
	return 0;
}


这样一来,你就能在你的训练模型代码的文件夹下生成MyFacePCAModel.xml这个东西,这个就是你经行人脸识别的基准。

4.人脸识别

前面的工作都做好了,这步就很简单了,将MyFacePCAModel.xml和haarcascade_frontalface_alt(haar人脸检测器是OpenCV自带的,在OpenCV自带的人脸识别代码文件夹里面能找到)放入指定代码的文件夹中,运行就好。

代码如下:

 

#include<opencv2opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

int main()
{
	VideoCapture cap(0);    //打开默认摄像头
	if (!cap.isOpened())
	{
		return -1;
	}
	Mat frame;
	Mat edges;
	Mat gray;

	CascadeClassifier cascade;
	bool stop = false;
	//训练好的文件名称,放置在可执行文件同目录下
	cascade.load("haarcascade_frontalface_alt.xml");

	Ptr<FaceRecognizer> modelPCA = createEigenFaceRecognizer();
	modelPCA->load("MyFacePCAModel.xml");
	
	while(!stop)
	{
		cap >> frame;

		//建立用于存放人脸的向量容器
		vector<Rect> faces(0);

		cvtColor(frame, gray, CV_BGR2GRAY);
		//改变图像大小,使用双线性差值
		//resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);
		//变换后的图像进行直方图均值化处理
		equalizeHist(gray, gray);

		cascade.detectMultiScale(gray, faces,
			1.1, 2, 0
			//|CV_HAAR_FIND_BIGGEST_OBJECT
			//|CV_HAAR_DO_ROUGH_SEARCH
			| CV_HAAR_SCALE_IMAGE,
			Size(30, 30));

		Mat face;
		Point text_lb;

		for (size_t i = 0; i < faces.size(); i++)
		{
			if (faces[i].height > 0 && faces[i].width > 0)
			{
				face = gray(faces[i]);
				text_lb = Point(faces[i].x, faces[i].y);

				rectangle(frame, faces[i], Scalar(255, 0, 0), 1, 8, 0);
			}
		}

		Mat face_test;

		int predictPCA = 0;
		if (face.rows >= 120)
		{
			resize(face, face_test, Size(92, 112));
			
		}
		//Mat face_test_gray;
		//cvtColor(face_test, face_test_gray, CV_BGR2GRAY);

		if (!face_test.empty())
		{
			//测试图像应该是灰度图
			predictPCA = modelPCA->predict(face_test);
		}

		cout << predictPCA << endl;
		if (predictPCA == 1)
		{
			string name = "ZBR";
			putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));
		}
		else
		{
		   string name = "No Person!";
			putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));
		}
		
		imshow("face", frame);
		if (waitKey(50) >= 0)
			stop = true;
	}

	return 0;
}

 

文件夹中有:

最终效果图:

 

  

到此就全部结束了,过程并不,重要的是要学会方法和原理。

如果感兴趣的也可以去了解下PCA算法,还有OpenCV机器学习的相关内容

最后

以上就是无聊心情为你收集整理的基于PCA算法的人脸识别制作自己的样本实现识别自己的人脸1.图像的采集及预处理2.csv文件的生成3.训练模型4.人脸识别的全部内容,希望文章能够帮你解决基于PCA算法的人脸识别制作自己的样本实现识别自己的人脸1.图像的采集及预处理2.csv文件的生成3.训练模型4.人脸识别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部