opencv人脸识别,识别视频中的库里

1.在网上采集人脸图片 

2.将采集的图片尺寸归一化,并转为灰度图

代码:

#include <opencv2/video/video.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <cstdio>
#include <windows.h>
using namespace std;
using namespace cv;
string path = "E:/kuli/";
string png = ".png";

int main()
{

	for (int i = 1; i < 56; i++) {
		Mat src = imread(path + to_string(i) + png);
		Mat dst = Mat(Size(48, 48), src.type());
		resize(src, dst, Size(48,48));
		cvtColor(dst, dst, COLOR_BGR2GRAY);
		imwrite("E:/kuli/kuli/" + to_string(i) + ".png", dst);
		
	}
	return 0;
}

 结果:

 3.制作标签文件CSV

代码:

#include <opencv2/video/video.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <cstdio>
#include<fstream>
#include <windows.h>
using namespace std;
using namespace cv;

int main()
{
	ofstream out("E:/kuli/kuli/at.txt");
	if (!out) {
		cout << "error" << endl;
	}
	for (int i = 1; i < 56; i++) {
		out << "E:/kuli/kuli/" + to_string(i) + ".png              ;1\n";
	}
	return 0;
}

结果:

 4.训练

注意:face.hpp在opencv2以上版本已经取消了,要想使用需要自行配置(我花了4个多小时,可能会把你劝退)看这篇文章:https://blog.csdn.net/qq_34360180/article/details/66978979 

//face_recog_from_video.cpp 定义控制台应用程序的入口点。

#include "opencv2/opencv.hpp"
#include "opencv2/face.hpp"
#include <stdio.h>
#include<iostream>

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

/** Function Headers */
void detectAndDisplay(Mat frame);
static  void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, int max, int min, char separator);

/** Global variables */
String face_cascade_name = "haarcascade_frontalface_default.xml";
CascadeClassifier face_cascade;
Ptr<EigenFaceRecognizer> modelPCA = EigenFaceRecognizer::create();// 创建特征脸模型  EigenFaceRecognizer

String window_name = "Capture - Face Recognition";

/** @function main */
int main(int argc, const char** argv)
{
	string csvFile = "at.txt";
	vector<Mat> images;
	vector<int> labels;
	int CountMax = 9, CountMin = 0;

	// 读取csv文件  
	try
	{
		read_csv(csvFile, images, labels, CountMax, CountMin, ';'); //读取csvFile中所有的img和label  
	}
	catch (cv::Exception& e) // 异常检查  
	{
		cerr << "Error opening file\" " << csvFile << "\".reason: " << e.msg << endl;
		exit(-1);
	}


	// 若未读取到足够图片,也退出  
	if (images.size() <= 1)
	{
		string errMsg = "THis demo needs at least 2 images to work.please add images!";
		CV_Error(CV_StsError, errMsg);

	}
	cout << "train1.读取ok" << endl;

	// 训练模型,并将训练好的人脸模型保存到.xml中   
	modelPCA->train(images, labels); //训练  
	modelPCA->save("MyFacePcaModel.xml");
	cout << "train2.创建脸模型ok" << endl;

	// 视频采集
	VideoCapture capture;
	Mat frame;

	//-- 1. Load the cascades
	if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); return -1; };

	//-- 2. Read the video stream
	capture.open(0); //打开摄像头
	if (!capture.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }

	while (capture.read(frame)) //读取帧
	{
		if (frame.empty())
		{
			printf(" --(!) No captured frame -- Break!");
			break;
		}

		//-- 3. Apply the classifier to the frame
		detectAndDisplay(frame);

		if (waitKey(10) == 'k') { break; } // escape  
	}
	return 0;
}

/** @function detectAndDisplay */
void detectAndDisplay(Mat frame)
{
	std::vector<Rect> faces;
	Mat frame_gray;

	cvtColor(frame, frame_gray, COLOR_BGR2GRAY);  //BGR 转化为灰度图
	equalizeHist(frame_gray, frame_gray);   //直方图均衡化
	//-- Detect faces
	face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(60, 60));

	for (size_t i = 0; i < faces.size(); i++)
	{
		Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2); // 人脸中心坐标
		ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0); // 椭圆

		Mat faceROI = frame_gray(faces[i]);
		Mat face_test;

		resize(faceROI, face_test, Size(200, 200)); // 调整大小为92*112 
		double confidence;
		int predictPCA;

		//modelPCA->load("MyFacePcaModel.xml");//加载模型
		modelPCA->predict(face_test, predictPCA, confidence);
		cout << "the predict result is " << predictPCA << endl << "confidence is " << confidence << endl;
		if (predictPCA == 1)
		{
			putText(frame, "Hello kuli", Point(faces[i].x, faces[i].y), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2);
		}
	}
	//-- Show what you got
	imshow(window_name, frame);
}


static  void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, int max, int min, char separator)
{
	std::ifstream  file(filename.c_str(), ifstream::in); // 以in模式(读取文件模式)打开文件 ,实际是将filename文件关联给 流file 

	if (!file)
	{
		string error_message = "No valid input file was given,please check the given filename";
		CV_Error(CV_StsBadArg, error_message);

	}
	int ii = 0;

	/**********************读取文件.txt内容****************************/
	string line, path, label;
	// [1]读取file文件中的一行字符串给 line  
	while (getline(file, line, '\n'))  // 控制:直到读到file文件末尾(eof标识),才跳出while  
	{
		// [2]将line整行字符串读取到lines(流)中  
		stringstream lines(line); //区别->lines是流,读取字符时,指针会随流而动;而line是string,固定的,下文中的读取每次都是从line头开始  
								  // [3]读取文件中的路径和标签  
		getline(lines, path, separator); //此时光标已走到path之后的位置(即;分号处)  
		getline(lines, label);
		// [4]将图片和标签加入imgs 和 labels  
		if ((path.empty() == 0) && (label.empty() == 0))
		{
			if (ii % 10 <= max && ii % 10 >= min)  //默认每个类别共10张照片  
			{
				Mat img = imread(path, 0);  //第二个参数为0 !!!  
											//Mat img = imread(ImageFileAddress, CV_LOAD_IMAGE_GRAYSCALE),CV_LOAD_IMAGE_GRAYSCALE值为 0,指灰图(原本为“CV_LOAD_IMAGE_UNCHANGED”)  
				if (img.data != 0)
				{
					images.push_back(img); // 将图片 添加到images中  
					labels.push_back(atoi(label.c_str()));
				}
			}
			if (ii < 9) ii++;
			else ii = 0;

		}
	}
}

结果:

博主忘了训练负样本,好像识别谁都是库里,哈哈哈。 

猜你喜欢

转载自blog.csdn.net/qq_40238526/article/details/90234158