当前位置:   article > 正文

OpenCV EigenFaceRecognizer 人脸识别_opencv-facerec

opencv-facerec

目录

一、人脸检测vs人脸识别

二、数据库

三、准备需要识别的人脸

四、人脸识别(OpenCV)


一、人脸检测vs人脸识别

人脸检测只是需要检测图像中是否有人脸,而人脸识别是一个程序能够识别出给定图像或者视频中的人脸

二、数据库

人脸数据库,这个博客有网盘链接。

三、准备需要识别的人脸

准备一个人的10张左右数量的人脸,放到刚刚下载ORL的数据库中:

 

捕获人脸代码:

  1. #include <iostream>
  2. #include <opencv2/opencv.hpp>
  3. #include <unistd.h>
  4. #include <sys/stat.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7. using namespace std;
  8. using namespace cv;
  9. void detectFace(Mat frame, string path)
  10. {
  11. // 级联分类器加载文件
  12. CascadeClassifier facefier;
  13. facefier.load("/home/jason/file/opencv/haarcascade_frontalface_alt.xml");
  14. VideoCapture capture(0);
  15. vector<Rect> faces;
  16. Mat gray_frame;
  17. int number=0;
  18. while (1)
  19. {
  20. capture >> frame;
  21. imshow("detect face", frame);
  22. cvtColor(frame,gray_frame,COLOR_BGR2GRAY);
  23. equalizeHist(gray_frame,gray_frame);
  24. // 检测人脸
  25. facefier.detectMultiScale(gray_frame, faces);
  26. // 保存人脸
  27. for (size_t i=0; i < faces.size(); i++)
  28. {
  29. // 画框标出人脸
  30. Mat temp = frame.clone();
  31. rectangle(temp,faces[i], Scalar(255, 0,0), 1, 8);
  32. imshow("detect face", temp);
  33. // 扣出人脸
  34. Mat faceROI = frame(faces[i]);
  35. // 过滤
  36. if (faceROI.cols * faceROI.rows > 100 * 100)
  37. {
  38. resize(faceROI, faceROI, Size(92, 112));
  39. string newpath = path + "/" + to_string(number) + ".png";
  40. imwrite(newpath,faceROI);
  41. cout << "file save :" << newpath << endl;
  42. imshow("ROI", faceROI);
  43. number++;
  44. }
  45. }
  46. if(waitKey() == 27)
  47. break;
  48. }
  49. cout << "you save " << number << " face images" << endl;
  50. }
  51. void generator(string path)
  52. {
  53. // 输入文件夹名字
  54. string name;
  55. cout << "Please key the name:\n";
  56. getline(cin, name);
  57. // 新建文件夹
  58. string newpath = path + "/" + name;
  59. cout << "image will save the path:" << newpath.c_str() << endl;
  60. if (!newpath.empty())
  61. {
  62. if(NULL != opendir(newpath.c_str()))
  63. {
  64. cout << "fin a dir same to your input! delete it now!" << endl;
  65. rmdir(newpath.c_str());
  66. }
  67. if (NULL == opendir(newpath.c_str()))
  68. {
  69. mkdir(newpath.c_str(),0777);
  70. }
  71. }
  72. // 检测人脸并扣出来保存到指定位置
  73. Mat frame;
  74. detectFace(frame, newpath);
  75. }
  76. int main()
  77. {
  78. string path = "/home/jason/file";
  79. generator(path);
  80. cout << "Hello World!" << endl;
  81. return 0;
  82. }

四、人脸识别(OpenCV)

 

实现代码:

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <dirent.h>
  6. #include <sys/stat.h>
  7. #include <opencv2/opencv.hpp>
  8. #include <opencv2/face/facerec.hpp>
  9. using namespace cv;
  10. using namespace std;
  11. int label=0;
  12. std::string nam;
  13. vector<Mat> images;
  14. vector<int> labels;
  15. vector<string> names;
  16. void Load_data(const std::string& path)
  17. {
  18. DIR* dir = opendir(path.c_str());
  19. if (dir == nullptr)
  20. {
  21. std::cerr << "Cannot open directory: " << path << std::endl;
  22. return;
  23. }
  24. struct dirent* entry;
  25. while ((entry = readdir(dir)) != nullptr)
  26. {
  27. std::string name = entry->d_name;
  28. if (name == "." || name == "..")
  29. {
  30. continue;
  31. }
  32. std::string fullPath = path + "/" + name;
  33. struct stat stat_buf;
  34. if (stat(fullPath.c_str(), &stat_buf) != 0)
  35. {
  36. std::cerr << "Cannot stat file: " << fullPath << std::endl;
  37. return;
  38. }
  39. // Determine whether it is a folder
  40. if (S_ISDIR(stat_buf.st_mode))
  41. {
  42. std::cout << "Directory: " << fullPath <<std::endl;
  43. Load_data(fullPath);
  44. // label name
  45. label+=1;
  46. nam=name;
  47. }
  48. else if (S_ISREG(stat_buf.st_mode))
  49. {
  50. std::cout << "File: " << fullPath
  51. << " name:" << nam
  52. << " label: "<<label<<std::endl;
  53. // 添加到容器中
  54. Mat img = imread(fullPath);
  55. images.push_back(img);
  56. labels.push_back(label);
  57. names.push_back(nam);
  58. }
  59. }
  60. closedir(dir);
  61. }
  62. void FaceRec(const string &path, string person_name="jack")
  63. {
  64. // 准备数据
  65. Load_data(path);
  66. // 训练
  67. // Ptr<cv::face::FaceRecognizer> model = cv::face::FisherFaceRecognizer::create();
  68. Ptr<cv::face::EigenFaceRecognizer> model = cv::face::EigenFaceRecognizer::create();
  69. // Ptr<cv::face::LBPHFaceRecognizer> model = cv::face::LBPHFaceRecognizer(1, 8,8,8,);
  70. model->train(images, labels);
  71. // 创建一个级联分类器 加载一个 .xml 分类器文件. 它既可以是Haar特征也可以是LBP特征的分类器.
  72. CascadeClassifier casc;
  73. casc.load("/home/jason/file/opencv/haarcascade_frontalface_alt.xml");
  74. int jack_label;
  75. for (size_t i=0; i<names.size(); i++)
  76. {
  77. if (names[i] == person_name)
  78. jack_label=labels[i];
  79. }
  80. VideoCapture capture(0);
  81. Mat frame, gray;
  82. vector<Rect> faces;
  83. while (1)
  84. {
  85. // 获取图像
  86. capture >> frame;
  87. imshow("recognizer", frame);
  88. // 预处理
  89. cvtColor(frame,gray,COLOR_RGB2GRAY);
  90. equalizeHist(gray, gray);
  91. // 检测人脸
  92. casc.detectMultiScale(gray, faces);
  93. // 扣出人脸判断是否为目标人物
  94. for(size_t i=0; i<faces.size(); i++)
  95. {
  96. Mat temp = frame.clone();
  97. rectangle(temp, faces[i], Scalar(255, 0, 0), 1, 8);
  98. Mat roi_gray = gray(faces[i]);
  99. resize(roi_gray, roi_gray, Size(92, 112));
  100. imshow("person",roi_gray);
  101. int result;
  102. double confidence=0.8;
  103. // 预测
  104. model->predict(roi_gray, result, confidence);
  105. cout<< "result: " << result
  106. <<"confidence: " << confidence<< endl;
  107. if (result==jack_label)
  108. {
  109. putText(temp, person_name ,Point(faces[i].x, faces[i].y),FONT_ITALIC,
  110. 0.5, Scalar(255, 0, 0),1,8);
  111. }
  112. else
  113. {
  114. cout << "not find " << person_name << endl;
  115. }
  116. imshow("recognizer", temp);
  117. }
  118. if (waitKey(10)==27) break;
  119. }
  120. }
  121. int main()
  122. {
  123. std::string path = "/home/jason/file/Face/ORL_Faces";
  124. FaceRec(path,"jack");
  125. return 1;
  126. }

参考资料:

C++创建文件夹和写文件_林多的博客-CSDN博客

C++11标准中遍历文件夹方法_c++11 遍历目录_HotPot_Dumplings的博客-CSDN博客

OpenCV: cv::face::FaceRecognizer Class Reference

https://www.cnblogs.com/zyly/p/9498857.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/278557
推荐阅读
相关标签
  

闽ICP备14008679号