赞
踩
目录
人脸检测只是需要检测图像中是否有人脸,而人脸识别是一个程序能够识别出给定图像或者视频中的人脸。
人脸数据库,这个博客有网盘链接。
准备一个人的10张左右数量的人脸,放到刚刚下载ORL的数据库中:
捕获人脸代码:
- #include <iostream>
- #include <opencv2/opencv.hpp>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <dirent.h>
-
- using namespace std;
- using namespace cv;
-
- void detectFace(Mat frame, string path)
- {
- // 级联分类器加载文件
- CascadeClassifier facefier;
- facefier.load("/home/jason/file/opencv/haarcascade_frontalface_alt.xml");
-
- VideoCapture capture(0);
- vector<Rect> faces;
- Mat gray_frame;
-
- int number=0;
- while (1)
- {
- capture >> frame;
- imshow("detect face", frame);
- cvtColor(frame,gray_frame,COLOR_BGR2GRAY);
- equalizeHist(gray_frame,gray_frame);
-
- // 检测人脸
- facefier.detectMultiScale(gray_frame, faces);
-
- // 保存人脸
- for (size_t i=0; i < faces.size(); i++)
- {
-
- // 画框标出人脸
- Mat temp = frame.clone();
- rectangle(temp,faces[i], Scalar(255, 0,0), 1, 8);
- imshow("detect face", temp);
-
- // 扣出人脸
- Mat faceROI = frame(faces[i]);
-
- // 过滤
- if (faceROI.cols * faceROI.rows > 100 * 100)
- {
- resize(faceROI, faceROI, Size(92, 112));
- string newpath = path + "/" + to_string(number) + ".png";
- imwrite(newpath,faceROI);
- cout << "file save :" << newpath << endl;
- imshow("ROI", faceROI);
- number++;
- }
-
- }
-
- if(waitKey() == 27)
- break;
-
- }
- cout << "you save " << number << " face images" << endl;
-
-
- }
-
- void generator(string path)
- {
-
- // 输入文件夹名字
- string name;
- cout << "Please key the name:\n";
- getline(cin, name);
-
-
- // 新建文件夹
- string newpath = path + "/" + name;
- cout << "image will save the path:" << newpath.c_str() << endl;
-
- if (!newpath.empty())
- {
- if(NULL != opendir(newpath.c_str()))
- {
- cout << "fin a dir same to your input! delete it now!" << endl;
- rmdir(newpath.c_str());
- }
-
- if (NULL == opendir(newpath.c_str()))
- {
- mkdir(newpath.c_str(),0777);
- }
-
- }
-
- // 检测人脸并扣出来保存到指定位置
- Mat frame;
- detectFace(frame, newpath);
-
- }
-
-
-
-
- int main()
- {
- string path = "/home/jason/file";
- generator(path);
- cout << "Hello World!" << endl;
- return 0;
- }
实现代码:
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <dirent.h>
- #include <sys/stat.h>
-
- #include <opencv2/opencv.hpp>
- #include <opencv2/face/facerec.hpp>
- using namespace cv;
- using namespace std;
-
- int label=0;
- std::string nam;
-
- vector<Mat> images;
- vector<int> labels;
- vector<string> names;
- void Load_data(const std::string& path)
- {
-
- DIR* dir = opendir(path.c_str());
- if (dir == nullptr)
- {
- std::cerr << "Cannot open directory: " << path << std::endl;
- return;
- }
-
- struct dirent* entry;
- while ((entry = readdir(dir)) != nullptr)
- {
- std::string name = entry->d_name;
- if (name == "." || name == "..")
- {
- continue;
- }
-
- std::string fullPath = path + "/" + name;
- struct stat stat_buf;
- if (stat(fullPath.c_str(), &stat_buf) != 0)
- {
- std::cerr << "Cannot stat file: " << fullPath << std::endl;
- return;
- }
- // Determine whether it is a folder
- if (S_ISDIR(stat_buf.st_mode))
- {
- std::cout << "Directory: " << fullPath <<std::endl;
- Load_data(fullPath);
-
-
- // label name
- label+=1;
- nam=name;
- }
- else if (S_ISREG(stat_buf.st_mode))
- {
- std::cout << "File: " << fullPath
- << " name:" << nam
- << " label: "<<label<<std::endl;
-
- // 添加到容器中
- Mat img = imread(fullPath);
-
- images.push_back(img);
- labels.push_back(label);
- names.push_back(nam);
- }
- }
- closedir(dir);
-
- }
-
- void FaceRec(const string &path, string person_name="jack")
- {
- // 准备数据
- Load_data(path);
-
- // 训练
- // Ptr<cv::face::FaceRecognizer> model = cv::face::FisherFaceRecognizer::create();
- Ptr<cv::face::EigenFaceRecognizer> model = cv::face::EigenFaceRecognizer::create();
- // Ptr<cv::face::LBPHFaceRecognizer> model = cv::face::LBPHFaceRecognizer(1, 8,8,8,);
- model->train(images, labels);
-
- // 创建一个级联分类器 加载一个 .xml 分类器文件. 它既可以是Haar特征也可以是LBP特征的分类器.
- CascadeClassifier casc;
- casc.load("/home/jason/file/opencv/haarcascade_frontalface_alt.xml");
-
- int jack_label;
-
- for (size_t i=0; i<names.size(); i++)
- {
- if (names[i] == person_name)
- jack_label=labels[i];
- }
-
- VideoCapture capture(0);
- Mat frame, gray;
- vector<Rect> faces;
-
- while (1)
- {
- // 获取图像
- capture >> frame;
-
- imshow("recognizer", frame);
-
- // 预处理
- cvtColor(frame,gray,COLOR_RGB2GRAY);
- equalizeHist(gray, gray);
-
- // 检测人脸
- casc.detectMultiScale(gray, faces);
-
- // 扣出人脸判断是否为目标人物
- for(size_t i=0; i<faces.size(); i++)
- {
- Mat temp = frame.clone();
- rectangle(temp, faces[i], Scalar(255, 0, 0), 1, 8);
-
- Mat roi_gray = gray(faces[i]);
- resize(roi_gray, roi_gray, Size(92, 112));
- imshow("person",roi_gray);
-
- int result;
- double confidence=0.8;
-
- // 预测
- model->predict(roi_gray, result, confidence);
- cout<< "result: " << result
- <<"confidence: " << confidence<< endl;
- if (result==jack_label)
- {
- putText(temp, person_name ,Point(faces[i].x, faces[i].y),FONT_ITALIC,
- 0.5, Scalar(255, 0, 0),1,8);
- }
- else
- {
- cout << "not find " << person_name << endl;
-
- }
- imshow("recognizer", temp);
- }
-
- if (waitKey(10)==27) break;
-
- }
- }
-
-
-
- int main()
- {
- std::string path = "/home/jason/file/Face/ORL_Faces";
- FaceRec(path,"jack");
- return 1;
- }
参考资料:
C++11标准中遍历文件夹方法_c++11 遍历目录_HotPot_Dumplings的博客-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。