opencv 人脸检测与识别

1.打开摄像头自动采集保存图片

void Autopic() {
	VideoCapture  capture(0);
	Mat frame;
	if (!capture.isOpened())
	{
		cout << "摄像头打开失败!" << endl;
		return;
	}
	char key;
	char filename[200];
	int count = 0;
	namedWindow("【视频】", 1);
	namedWindow("【图片】", 1);
	while (1)
	{
		key = waitKey(50);
		capture >> frame;
		imshow("【视频】", frame);

		if (key == 27)
			break;//按ESC键退出程序  
		if (key == 32)//按空格键进行拍照  
		{
			sprintf_s(filename, "img/Picture %d.jpg", ++count);
			imwrite(filename, frame);//图片保存到本工程目录中  
			imshow("【图片】", frame);
		}
	}
}

2.检测人脸调整图片大小为人脸识别做准备

void ResizeFace() {
	CascadeClassifier faceCascade;
	faceCascade.load("D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径
	
	
	for (int i = 1; i < 33; i++) {
		stringstream ss;
		ss << i;
		Mat img = imread("img/Picture "+ss.str()+".jpg");
		
		std::vector<Rect> faces;
		Mat img_gray;

		cvtColor(img, img_gray, COLOR_BGR2GRAY);
		equalizeHist(img_gray, img_gray);

		//-- Detect faces  
		//faceCascade.detectMultiScale(img_gray, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(50, 50));
		faceCascade.detectMultiScale(img_gray, faces, 1.2, 6, 0, Size(0, 0));   //检测人脸
		for (size_t j = 0; j < faces.size(); j++)
		{
			Mat faceROI = img(faces[j]);
			Mat MyFace;
			if (faceROI.cols > 100)
			{
				resize(faceROI, MyFace, Size(92, 112));
				string  str = format("img/43/MyFcae%d.jpg", i);
				imwrite(str, MyFace);
				//imshow("ii", MyFace);
			}
			//waitKey(10);
		}
	}

}
3.训练模型

void trainmodel() {
	//读取你的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:自然这里需要根据自己的需要修改,他这里简化了很多问题]  
	Mat testSample = images[images.size() - 1];
	int testLabel = labels[labels.size() - 1];
	images.pop_back();
	labels.pop_back();
	// 下面几行创建了一个特征脸模型用于人脸识别,  
	// 通过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");

	Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer();
	model1->train(images, labels);
	model1->save("MyFaceFisherModel.xml");

	Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
	model2->train(images, labels);
	model2->save("MyFaceLBPHModel.xml");

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

	// 还有一种调用方式,可以获取结果同时得到阈值:  
	//      int predictedLabel = -1;  
	//      double confidence = 0.0;  
	//      model->predict(testSample, predictedLabel, confidence);  

	string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
	string result_message1 = format("Predicted class = %d / Actual class = %d.", predictedLabel1, testLabel);
	string result_message2 = format("Predicted class = %d / Actual class = %d.", predictedLabel2, testLabel);
	cout << result_message << endl;
	cout << result_message1 << endl;
	cout << result_message2 << endl;

	waitKey(0);
}

需要注意的是
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
可能会报错,需要加载#include<opencv2\face.hpp> 如果没有face.hpp就需要

添加OpenCV_contrib库至OpenCV3.1.0中  具体参考 http://blog.csdn.net/liu798675179/article/details/51259505

at.txt是图片文件对应的标签内容格式如下:

可用Python自动生成上述文件代码如下:
#!/usr/bin/env python  
  
import sys  
import os.path  
  
# This is a tiny script to help you creating a CSV file from a face  
# database with a similar hierarchie:  
#  
#  philipp@mango:~/facerec/data/at$ tree  
#  .  
#  |-- README  
#  |-- s1  
#  |   |-- 1.pgm  
#  |   |-- ...  
#  |   |-- 10.pgm  
#  |-- s2  
#  |   |-- 1.pgm  
#  |   |-- ...  
#  |   |-- 10.pgm  
#  ...  
#  |-- s40  
#  |   |-- 1.pgm  
#  |   |-- ...  
#  |   |-- 10.pgm  
#  
  
if __name__ == "__main__":  
  
    #if len(sys.argv) != 2:  
    #    print "usage: create_csv <base_path>"  
    #    sys.exit(1)
    #BASE_PATH=sys.argv[1]  
    BASE_PATH="F:/AIRobot/opencv/FaceRecognize/FaceRecognize/img/faceimg/orl_faces"
    SEPARATOR=";"
    fh = open("at.txt",'w')

    label = 0  
    for dirname, dirnames, filenames in os.walk(BASE_PATH):  
        for subdirname in dirnames:  
            subject_path = os.path.join(dirname, subdirname)  
            for filename in os.listdir(subject_path):  
                abs_path = "%s/%s" % (subject_path, filename)  
                print ("%s%s%d" % (abs_path, SEPARATOR, label))
                fh.write(abs_path)  
                fh.write(SEPARATOR)  
                fh.write(str(label))  
                fh.write("\n")        
            label = label + 1  
    fh.close()



4.进行预测
void testpre() {

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

		CascadeClassifier cascade;
		bool stop = false;
		//训练好的文件名称,放置在可执行文件同目录下  
		cascade.load("D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.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 == 3)
			{
				string name = "Yang";
				putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));
			}
			else if (predictPCA == 4)
			{
				string name = "Gu";
				putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));
			}
			else if (predictPCA == 5)
			{
				string name = "5";
				putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));
			}
			imshow("face", frame);
			if (waitKey(50) >= 0)
				stop = true;
		}

}
参考:http://blog.csdn.net/xingchenbingbuyu/article/details/51386949







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AICVer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值