Opencv代码实现人脸识别
程序功能:能够利用摄像头自主检测人脸,检测到人脸后才进入人脸识别子函数,与识别模板进行比对,通过PCA算法进行人脸识别,若识别为模板人脸,则在视频上显示姓名。
程序流程:
-
打开摄像头
-
拍摄自己的头像,作为人脸检测模型,写入磁盘
-
加载人脸检测器,加载人脸模型
-
人脸检测
-
把检测到的人脸与人脸模型里面的对比,找出这是谁的脸
-
如果人脸是自己的,显示自己的名字。
人脸检测的数据集的获取方法参考博客OpenCV实践之路——人脸识别之一数据收集和预处理
代码[3]:
#include<opencv2/opencv.hpp> #include<iostream> #include<stdio.h> #include<fstream> #include<sstream> #include<math.h> using namespace cv; using namespace std; using namespace face; const char ESC = 27; String face_cascade_name = "G://openCV/opencv3.2.0/opencv/sources/data/haarcascades_cuda/haarcascade_frontalface_default.xml"; String eyes_cascade_name = "G://openCV/opencv3.2.0/opencv/sources/data/haarcascades_cuda/haarcascade_eye_tree_eyeglasses.xml"; CascadeClassifier face_cascade;//定义人脸分类器 / //使用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 predictVedio(Ptr<FaceRecognizer>& model, vector<int>& labels) { VideoCapture cap(0); std::vector<Rect> faces; Mat frame_gray; Mat frame; char key = waitKey(100);//等待100ms,返回键盘上的字符 cap >> frame; //检测人脸,检测到人脸才允许拍照 if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); return 0; };//读取分类器 cvtColor(frame, frame_gray, COLOR_BGR2GRAY); equalizeHist(frame_gray, frame_gray); face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, CV_HAAR_DO_ROUGH_SEARCH, Size(70, 70), Size(100, 100)); Mat faceROI; for (size_t j = 0; j < faces.size(); j++) { Point center(faces[j].x + faces[j].width / 2, faces[j].y + faces[j].height / 2); rectangle(frame, faces[j], Scalar(255, 0, 0), 2, 8, 0); faceROI = frame_gray(faces[j]); } /// Point text_lb; for (size_t i = 0; i < faces.size(); i++) { if (faces[i].height > 0 && faces[i].width > 0) { text_lb = Point(faces[i].x, faces[i].y); } } if (faces.size() != 0) { resize(faceROI, faceROI, Size(92, 112)); int predictedLabel = model->predict(faceROI); if (predictedLabel == 40) { string name = "Hao"; putText(frame, name, text_lb, FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255)); } }imshow("frame", frame); if (key == ESC) { return 0; } return 1; } int main() { //读取CSV文件路径 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 you data set!"; CV_Error(CV_StsError, error_message); } //下面几行创建了一个特征脸模型用于人脸识别, //通过CSV文件读取的图像和标签训练它 //T这里是一个完整的PCA变换 //如果你只想保留10个主成份,使用如下代码 // cv::createEigenFaceRecognizer(10); // //如果你还希望使用置信度阈值来初始化,使用以下语句: // cv::createEigenFaceRecognizer(10,123.0); //如果你使用所有特征并且使用一个阈值,使用以下语句:` // cv::createEigenFaceRecognizer(0,123.0); Ptr<FaceRecognizer> model = createEigenFaceRecognizer();//基于PCA变换的人脸识别算法 model->train(images, labels); model->load("MyFacePCAModel.xml"); while (1) { if (!predictVedio(model,labels)) { break; } }/**/ waitKey(0); return 0; }
参考文献
[2] PCA人脸识别
-
基于OpenCV的人脸识别算法之二---代码实现
最新推荐文章于 2024-08-18 08:40:42 发布