当前位置:   article > 正文

openCV学习笔记(十) —— 人脸检测之面部特征(眼睛、鼻子、嘴巴)_opencv 人脸识别人脸特征嘴巴不准确

opencv 人脸识别人脸特征嘴巴不准确

环境:VS2017

版本:3.4.1

 

人脸面部特征检测的准确性依赖于学习到的分类器

分类器可以从以下地址下载:https://github.com/opencv/opencv_contrib/tree/master/modules/face/data/cascades

也可以从下载contrib模块,从以下路径获得:opencv_contrib_3.4.1\modules\face\data\cascades

 

程序

  1. /*
  2. 人脸面部检测:人脸、眼睛、鼻子、嘴
  3. 检测的准确度依赖于分类器
  4. */
  5. #include <opencv2/objdetect.hpp>
  6. #include <opencv2/highgui.hpp>
  7. #include <opencv2/imgproc.hpp>
  8. #include <iostream>
  9. #include <vector>
  10. using namespace std;
  11. using namespace cv;
  12. void detectFaces(Mat &img, vector<Rect> &faces, string cascade_path);
  13. void detectFacialFeatures(Mat &img, vector<Rect> faces, string eye_cascade, string nose_cascade, string mouth_cascade);
  14. void detectEyes(Mat &img, vector<Rect> &eyes, string cascade_path);
  15. void detectNose(Mat &img, vector<Rect> &nose, string cascade_path);
  16. void detectMouth(Mat &img, vector<Rect> &mouth, string cascade_path);
  17. int main()
  18. {
  19. string input_image_path = "test1.jpg";
  20. string face_cascade_path = ".\\cascade\\haarcascades\\haarcascade_frontalface_default.xml";
  21. string eye_cascade_path = ".\\cascade\\haarcascades\\haarcascade_eye.xml";
  22. string nose_cascade_path = ".\\cascade\\haarcascades\\haarcascade_mcs_nose.xml";
  23. string mouth_cascade_path = ".\\cascade\\haarcascades\\haarcascade_mcs_mouth.xml";
  24. Mat img, imgGray;
  25. img = imread(input_image_path);
  26. if (img.empty())
  27. {
  28. printf("can't open image\n");
  29. return -1;
  30. }
  31. cvtColor(img, imgGray, CV_BGR2GRAY); //转换成灰度图来加快人脸识别的速度
  32. equalizeHist(imgGray, imgGray); //直方图均衡化
  33. //检测人脸和面部特征
  34. vector<Rect> faces;
  35. detectFaces(img, faces, face_cascade_path);
  36. detectFacialFeatures(img, faces, eye_cascade_path, nose_cascade_path, mouth_cascade_path);
  37. imshow("Result", img);
  38. waitKey(0);
  39. destroyAllWindows();
  40. return 0;
  41. }
  42. void detectFaces(Mat &img, vector<Rect> &faces, string cascade_path)
  43. {
  44. CascadeClassifier face_cascade;
  45. face_cascade.load(cascade_path);
  46. if (face_cascade.empty())
  47. {
  48. printf("can't load face cascade file\n");
  49. return;
  50. }
  51. face_cascade.detectMultiScale(img, faces, 1.1, 3, 0, Size(30, 30));
  52. return;
  53. }
  54. void detectFacialFeatures(Mat &img, vector<Rect> faces, string eye_cascade, string nose_cascade, string mouth_cascade)
  55. {
  56. printf("face_size = %zd\n", faces.size());
  57. for (int i = 0; i < faces.size(); i++)
  58. {
  59. Rect face = faces[i];
  60. rectangle(img, Point(face.x, face.y), Point(face.x + face.width, face.y + face.height), Scalar(255, 0, 0), 2, 4);
  61. //眼睛、鼻子和嘴巴将在脸部(感兴趣的区域)被检测到。
  62. Mat ROI = img(Rect(face.x, face.y, face.width, face.height));
  63. //检测眼睛、鼻子和嘴巴是否全部被检测到
  64. bool is_full_detection = false;
  65. if ((!eye_cascade.empty()) && (!nose_cascade.empty()) && (!mouth_cascade.empty()))
  66. {
  67. is_full_detection = true;
  68. }
  69. //用户提供的分类器可以检测眼睛
  70. if (!eye_cascade.empty())
  71. {
  72. vector<Rect> eyes;
  73. detectEyes(ROI, eyes, eye_cascade);
  74. //标记点与眼睛的中心相对应
  75. printf("eyes_size = %zd\n", eyes.size());
  76. for (int i = 0; i < eyes.size(); i++)
  77. {
  78. Rect e = eyes[i];
  79. circle(ROI, Point(e.x + e.width / 2, e.y + e.height / 2), 3, Scalar(0, 255, 0), -1, 8);
  80. //rectangle(ROI, Point(e.x, e.y), Point(e.x + e.width, e.y + e.height), Scalar(0, 255, 0), -1, 8);
  81. }
  82. }
  83. //用户提供的分类器可以检测鼻子
  84. double nose_center_height = 0;
  85. if (!nose_cascade.empty())
  86. {
  87. vector <Rect> nose;
  88. detectNose(ROI, nose, nose_cascade);
  89. //标记点与鼻子的中心相对应
  90. printf("nose_size = %zd\n", nose.size());
  91. for (int i = 0; i < nose.size(); i++)
  92. {
  93. Rect n = nose[i];
  94. circle(ROI, Point(n.x + n.width / 2, n.y + n.height / 2), 3, Scalar(0, 255, 0), -1, 8);
  95. nose_center_height = (n.y + n.height / 2);
  96. }
  97. }
  98. //用户提供的分类器可以检测嘴巴
  99. double mouth_center_height = 0;
  100. if (!mouth_cascade.empty())
  101. {
  102. vector<Rect> mouth;
  103. detectMouth(ROI, mouth, mouth_cascade);
  104. printf("mouth.size = %zd\n", mouth.size());
  105. for (int i = 0; i < mouth.size(); i++)
  106. {
  107. Rect m = mouth[i];
  108. mouth_center_height = (m.y + m.height / 2);
  109. if (is_full_detection && (mouth_center_height > nose_center_height))
  110. {
  111. rectangle(ROI, Point(m.x, m.y), Point(m.x + m.width, m.y + m.height), Scalar(0, 255, 0), 1, 4);
  112. }
  113. else if (is_full_detection && (mouth_center_height <= nose_center_height))
  114. {
  115. continue;
  116. }
  117. else
  118. {
  119. rectangle(ROI, Point(m.x, m.y), Point(m.x + m.width, m.y + m.height), Scalar(0, 255, 0), 1, 4);
  120. }
  121. }
  122. }
  123. }
  124. return;
  125. }
  126. void detectEyes(Mat &img, vector<Rect> &eyes, string cascade_path)
  127. {
  128. CascadeClassifier eyes_cascade;
  129. eyes_cascade.load(cascade_path);
  130. eyes_cascade.detectMultiScale(img, eyes, 1.20, 5, 0, Size(30, 30));
  131. return;
  132. }
  133. void detectNose(Mat &img, vector<Rect> &nose, string cascade_path)
  134. {
  135. CascadeClassifier nose_cascade;
  136. nose_cascade.load(cascade_path);
  137. nose_cascade.detectMultiScale(img, nose, 1.20, 5, 0, Size(30, 30));
  138. return;
  139. }
  140. void detectMouth(Mat &img, vector<Rect> &mouth, string cascade_path)
  141. {
  142. CascadeClassifier mouth_cascade;
  143. mouth_cascade.load(cascade_path);
  144. mouth_cascade.detectMultiScale(img, mouth, 1.20, 5, 0, Size(30, 30));
  145. return;
  146. }

 

运行结果

从运行结果来看,嘴巴的检测不够准确。

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

闽ICP备14008679号