代码C++, opencv实现人脸识别,人脸检测,人脸匹配,视频中的人脸检测,摄像头下的人脸检测等

代码C++, opencv实现人脸识别,人脸检测,人脸匹配,视频中的人脸检测,摄像头下的人脸检测等

2018-01-22 19:59:20 易大飞 阅读数 8291更多

分类专栏: CV 人脸对齐,人脸检测

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/stf1065716904/article/details/79132793

前一段时间写了一个人脸相关的算法,包括视频中的人脸检测,相机的人脸检测,图像中人脸检测,还有人脸识别。

使用的是VS2013和opencv。

首先创建头文件common.h

 

 
  1. #ifndef _COMMON_H

  2. #define _COMMON_H

  3.  
  4. #include <opencv2/opencv.hpp>

  5. #include <opencv2/highgui/highgui.hpp>

  6. #include <opencv2/imgproc/imgproc.hpp>

  7. #include <iostream>

  8. #include <sys/types.h>

  9. #include <sys/stat.h>

  10. #include <fstream>

  11. #include <string>

  12. #include <ctime>

  13. #include <io.h>

  14. #include <direct.h>

  15. //#include <cstdlib>

  16.  
  17.  
  18. static const char help[] = "face detection on image: needs image\n" \

  19. "face detection on video: needs video\n" \

  20. "face detection on camera: needs camera\n" \

  21. "face recognition: needs images\n";

  22.  
  23. /*

  24. 功能:判断该路径指向的是文件还是文件夹

  25.  
  26. 函数:isFileOrFolder

  27.  
  28. 文件返回: 0

  29. 文件夹返回: 1

  30. */

  31. bool isFileOrFolder(const std::string fileName);

  32.  
  33. #endif

然后就是创建common.cpp文件,这里面有相关的实现。

 

 

 
  1. #include "common.h"

  2.  
  3. bool isFileOrFolder(const std::string fileName)

  4. {

  5. const char* path = fileName.c_str();

  6. struct _stat buf = { 0 };

  7. _stat(path, &buf);

  8. return buf.st_mode & _S_IFDIR;

  9. }

然后就是视频中的人脸检测创建文件face_detection_video.h

 

 

 
  1. #ifndef _FACE_DETETION_VIDEO_H_

  2. #define _FACE_DETETION_VIDEO_H_

  3.  
  4. #include "common.h"

  5. void face_detetion_video(const std::string videoPath, const std::string cascadeName);

  6.  
  7. #endif

 

接着创建对应的cpp文件,face_detection_video.cpp

 

 
  1. #include "face_deteion_video.h"

  2.  
  3. void face_detetion_video(const std::string videoPath, const std::string cascadeName)

  4. {

  5. cv::VideoCapture cap(videoPath);

  6. if (!cap.isOpened())

  7. {

  8. std::cout << "不能打开该视频文件!" << std::endl;

  9. return;

  10. }

  11.  
  12. double scale = 2;

  13. cv::CascadeClassifier cascade;

  14. cascade.load(cascadeName);

  15. std::vector<cv::Rect> faces;

  16.  
  17. double fps = cap.get(CV_CAP_PROP_FPS); //获取帧率

  18.  
  19. bool isVideoRewriteFile = true; // 是否把视频重新写入文件, 默认是false:不重新写入文件

  20. double dWidth = 0;

  21. double dHeight = 0;

  22. cv::Size frameSize;

  23. cv::VideoWriter vdWr;

  24. if (isVideoRewriteFile)

  25. {

  26. dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);

  27. dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);

  28. frameSize = cv::Size(static_cast<int>(dWidth), static_cast<int>(dHeight));

  29.  
  30. size_t pos = videoPath.find_last_of('.');

  31. std::string videoWritePath = videoPath.substr(0, pos);

  32. videoWritePath = videoWritePath + "_Result.avi";

  33. vdWr = cv::VideoWriter(videoWritePath, CV_FOURCC('M', 'J', 'P', 'G'), fps, frameSize, true);

  34. if (!vdWr.isOpened())

  35. {

  36. std::cout << "不能写入视频!" << std::endl;

  37. isVideoRewriteFile = false;

  38. }

  39. }

  40.  
  41. while (1)

  42. {

  43. cv::Mat_<uchar> frame;

  44. bool bSuccess = cap.read(frame);

  45. if (!bSuccess)

  46. {

  47. break;

  48. }

  49.  
  50. cv::Mat smallImg(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入

  51. cv::resize(frame, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);

  52. cvtColor(smallImg, smallImg, CV_RGB2GRAY);

  53. cv::equalizeHist(smallImg, smallImg); //equalizeHist提高图像的亮度和对比度

  54.  
  55. cascade.detectMultiScale(smallImg, faces,

  56. 1.1, 2, 0

  57. /*|CV_HAAR_FIND_BIGGEST_OBJECT

  58. |CV_HAAR_DO_ROUGH_SEARCH*/

  59. | CV_HAAR_SCALE_IMAGE

  60. ,

  61. cv::Size(30, 30));

  62.  
  63. for (std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){

  64. cv::Rect rect(0, 0, 0, 0);

  65.  
  66. rect.x = int(r->x*scale);

  67. rect.y = int(r->y*scale);

  68. rect.width = int((r->width - 1)*scale);

  69. rect.height = int((r->height - 1)*scale);

  70.  
  71. cv::rectangle(frame, rect, cv::Scalar(0, 0, 0), 3, 8);

  72. }

  73.  
  74. //是否把检测结果写入文件

  75. if (isVideoRewriteFile)

  76. {

  77. vdWr.write(frame);

  78. }

  79.  
  80. cv::imshow("Video", frame);

  81. cv::waitKey((int)(1000 / fps));

  82.  
  83. }

  84.  
  85. cap.release();

  86. vdWr.release();

  87. }

然后是图像中的寻找人脸,文件名face_detection_img.h

 

 

 
  1. #ifndef _FACE_DETETION_IMAGE_H_

  2. #define _FACE_DETETION_IMAGE_H_

  3.  
  4. #include "common.h"

  5.  
  6. void face_detetion_img(const std::string imagePath, const std::string cascadeName);

  7.  
  8.  
  9.  
  10. #endif


接着就是对应头文件face_detection_img.cpp

 

 

 
  1. #include "face_detetion_img.h"

  2.  
  3.  
  4. void face_detetion_img(const std::string imgPath, const std::string cascadeName)

  5. {

  6. //bool fileOrFolder = isFileOrFolder(imgPath);

  7.  
  8. std::ifstream fin;

  9. fin.open(imgPath);

  10.  
  11. cv::CascadeClassifier cascade;

  12. double scale = 1.3;

  13. std::vector<cv::Rect> faces;

  14. cv::Mat gray;

  15.  
  16. // --Detection

  17. cascade.load(cascadeName);

  18. std::string name;

  19. while (getline(fin, name)){

  20. name.erase(0, name.find_first_not_of(" \t"));

  21. name.erase(name.find_last_not_of(" \t") + 1);

  22.  
  23. // Read Image

  24. cv::Mat_<uchar> image = cv::imread(name, 0);

  25. if (image.empty())

  26. {

  27. continue;

  28. }

  29.  
  30. // Read Opencv Detection Bbx

  31. cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入

  32. cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);

  33. cv::equalizeHist(smallImg, smallImg); //equalizeHist提高图像的亮度和对比度

  34. // --Detection

  35. cascade.detectMultiScale(smallImg, faces,

  36. 1.1, 2, 0

  37. /*|CV_HAAR_FIND_BIGGEST_OBJECT

  38. |CV_HAAR_DO_ROUGH_SEARCH*/

  39. | CV_HAAR_SCALE_IMAGE

  40. ,

  41. cv::Size(30, 30));

  42. for (std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){

  43. cv::Rect rect(0, 0, 0, 0);

  44.  
  45. rect.x = int(r->x*scale);

  46. rect.y = int(r->y*scale);

  47. rect.width = int((r->width - 1)*scale);

  48. rect.height = int((r->height - 1)*scale);

  49.  
  50. cv::rectangle(image, rect, cv::Scalar(0, 255, 0), 3, 8);

  51. }

  52.  
  53. cv::imshow("test", image);

  54. char s = cv::waitKey(0);

  55. if ('s' == s )

  56. {

  57. size_t pos = name.find_last_of('.');

  58. std::string filename = name.substr(0, pos);

  59.  
  60. filename = filename + ".bmp";

  61. std::cout << filename << std::endl;

  62. cv::imwrite(filename, image);

  63. }

  64. }

  65. fin.close();

  66. }


然后就是从摄像投中读取人脸信息。创建文件face_detection_camera.h

 

 

 
  1. #ifndef _FACE_DETETION_CAMERA_H_

  2. #define _FACE_DETETION_CAMERA_H_

  3.  
  4. #include "common.h"

  5. void face_detetion_camera(const std::string cascadeName);

  6.  
  7. #endif

接着就是对应cpp文件,face_detection_camera.cpp

 

 

 
  1. #include "face_detetion_camera.h"

  2.  
  3. void face_detetion_camera(const std::string cascadeName)

  4. {

  5. cv::VideoCapture cap(0);

  6. if (!cap.isOpened())

  7. {

  8. std::cout << "不能打开该视频文件!" << std::endl;

  9. return;

  10. }

  11.  
  12. double scale = 2;

  13. cv::CascadeClassifier cascade;

  14. cascade.load(cascadeName);

  15. std::vector<cv::Rect> faces;

  16.  
  17. bool isVideoRewriteFile = false; // 是否把摄像头读取的数据写入文件。

  18. double dWidth = 0;

  19. double dHeight = 0;

  20. cv::Size frameSize;

  21. cv::VideoWriter vdWr;

  22. char tmp[1024] = { 0 };

  23. if (isVideoRewriteFile)

  24. {

  25. dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);

  26. dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);

  27. frameSize = cv::Size(static_cast<int>(dWidth), static_cast<int>(dHeight));

  28.  
  29. time_t t = time(0);

  30. memset(tmp, 0, sizeof(tmp));

  31. strftime(tmp, sizeof(tmp), "../camera_out_video/%Y.%m.%d-%H.%M.%S", localtime(&t));

  32. std::string videoWritePath(tmp);

  33. videoWritePath = videoWritePath + ".avi";

  34. vdWr = cv::VideoWriter(videoWritePath, CV_FOURCC('M', 'J', 'P', 'G'), 20, frameSize, true);

  35. if (!vdWr.isOpened())

  36. {

  37. std::cout << "不能写入视频!" << std::endl;

  38. isVideoRewriteFile = false;

  39. }

  40. }

  41.  
  42. while (1)

  43. {

  44. cv::Mat frame;

  45. bool bSuccess = cap.read(frame);

  46. if (!bSuccess)

  47. {

  48. break;

  49. }

  50.  
  51. cv::Mat smallImg(cvRound(frame.rows / scale), cvRound(frame.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入

  52. cv::resize(frame, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);

  53. cvtColor(smallImg, smallImg, CV_RGB2GRAY);

  54. cv::equalizeHist(smallImg, smallImg); //equalizeHist提高图像的亮度和对比度

  55.  
  56. cascade.detectMultiScale(smallImg, faces,

  57. 1.1, 2, 0

  58. /*|CV_HAAR_FIND_BIGGEST_OBJECT

  59. |CV_HAAR_DO_ROUGH_SEARCH*/

  60. | CV_HAAR_SCALE_IMAGE

  61. ,

  62. cv::Size(30, 30));

  63.  
  64. for (std::vector<cv::Rect>::const_iterator r = faces.begin(); r != faces.end(); r++){

  65. cv::Rect rect(0, 0, 0, 0);

  66.  
  67. rect.x = int(r->x*scale);

  68. rect.y = int(r->y*scale);

  69. rect.width = int((r->width - 1)*scale);

  70. rect.height = int((r->height - 1)*scale);

  71.  
  72. cv::rectangle(frame, rect, cv::Scalar(0, 0, 0), 3, 8);

  73. }

  74.  
  75. //是否把检测结果写入文件

  76. if (isVideoRewriteFile)

  77. {

  78. vdWr.write(frame);

  79. }

  80.  
  81. cv::imshow("Video", frame);

  82. if (27 == cv::waitKey(20)){ // 按下ESC键,结束视频

  83. break;

  84. }

  85.  
  86. }

  87.  
  88. cap.release();

  89. vdWr.release();

  90. }

最后是人脸识别的头文件:face_recognition.h

 

 

 
  1. #ifndef _FACE_RECOGNITION_H_

  2. #define _FACE_RECOGNITION_H_

  3.  
  4. #include "common.h"

  5.  
  6. void preDeal_original_img(const std::string recognitionPath, const std::string cascadeName);

  7. std::vector<std::pair<cv::Mat, std::string >> get_CropFace_And_ImgPathName(const std::string recognitionPath, const std::string cascadeName);

  8. bool matchFace(cv::Mat detectFace, cv::Mat dbFace);

  9. void face_recognition(std::string recognitionPath, const std::string cascadeName);

  10.  
  11. #endif

 

以及对应的cpp文件:face_recognition.cpp

 
  1. #include "face_recognition.h"

  2.  
  3. void preDeal_original_img(const std::string recognitionPath, const std::string cascadeName)

  4. {

  5. std::ifstream fin;

  6. fin.open(recognitionPath);

  7. if (!fin)

  8. {

  9. std::cout << "Cannot open " + recognitionPath << std::endl;

  10. return;

  11. }

  12.  
  13. // --Detection

  14. cv::CascadeClassifier cascade;

  15. cascade.load(cascadeName);

  16. if (cascade.empty())

  17. {

  18. std::cout << "Cascade path error!" << std::endl;

  19. return;

  20. }

  21.  
  22. double scale = 1.3;

  23. std::vector<cv::Rect> faces;

  24. cv::Mat gray;

  25.  
  26. std::string name;

  27. std::string camera_face = "../camera_face/";

  28. while (getline(fin, name)){

  29. if (name.empty())

  30. {

  31. continue;

  32. }

  33. name.erase(0, name.find_first_not_of(" \t"));

  34. name.erase(name.find_last_not_of(" \t") + 1);

  35.  
  36. // Read Image

  37. cv::Mat img = cv::imread(name);

  38. if (img.empty())

  39. {

  40. continue;

  41. }

  42.  
  43. cv::Mat_<uchar> image;

  44. if (img.channels() != 1)

  45. {

  46. cvtColor(img, image, CV_BGR2GRAY);

  47. image.convertTo(image, CV_8UC1);

  48. }

  49. else{

  50. image = img;

  51. }

  52.  
  53.  
  54. // 改变图像

  55. cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入

  56. cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);

  57. cv::equalizeHist(smallImg, smallImg); //equalizeHist提高图像的亮度和对比度

  58. // --Detection

  59. cascade.detectMultiScale(smallImg, faces,

  60. 1.1, 3, 0

  61. /*|CV_HAAR_FIND_BIGGEST_OBJECT

  62. |CV_HAAR_DO_ROUGH_SEARCH*/

  63. | CV_HAAR_SCALE_IMAGE

  64. ,

  65. cv::Size(30, 30));

  66. if (faces.size() > 0)

  67. {

  68. size_t pos = name.find_last_of('\\');

  69. std::string filename = name.substr(pos + 1);

  70.  
  71. if (-1 == _access(camera_face.c_str(), 0))

  72. {

  73. _mkdir(camera_face.c_str());

  74. }

  75.  
  76. filename = camera_face + filename;

  77. std::cout << filename << std::endl;

  78. cv::imwrite(filename, img);

  79. }

  80.  
  81. }

  82. fin.close();

  83.  
  84. //处理后的图片路径名写入Path_Image.txt中

  85. std::string getImgPathTxt = "cd " + camera_face + " && dir /b/s/p/w *.jpg > Path_Images.txt";

  86. system(getImgPathTxt.c_str());

  87. }

  88.  
  89. std::vector<std::pair<cv::Mat, std::string >> get_CropFace_And_ImgPathName(const std::string recognitionPath, const std::string cascadeName)

  90. {

  91. std::vector<std::pair<cv::Mat, std::string>> cropFaceAndImgPathNames;

  92. std::pair<cv::Mat, std::string> cropFaceAndImgPathName;

  93.  
  94. cv::CascadeClassifier cascade;

  95. cascade.load(cascadeName);

  96. if (cascade.empty())

  97. {

  98. std::cout << "Cascade path error!" << std::endl;

  99. return std::vector<std::pair<cv::Mat, std::string >>();

  100. }

  101.  
  102. std::ifstream fdatabase;

  103. fdatabase.open(recognitionPath);

  104. if (!fdatabase)

  105. {

  106. std::cout << "Cannot open " + recognitionPath << std::endl;

  107. return std::vector<std::pair<cv::Mat, std::string >>();

  108. }

  109.  
  110. double scale = 1.3;

  111. std::vector<cv::Rect> faces;

  112. cv::Mat gray;

  113. std::string name;

  114.  
  115. std::cout << "[";

  116.  
  117. while (getline(fdatabase, name)){

  118. if (name.empty())

  119. {

  120. continue;

  121. }

  122. name.erase(0, name.find_first_not_of(" \t"));

  123. name.erase(name.find_last_not_of(" \t") + 1);

  124.  
  125. // Read Image

  126. cv::Mat img = cv::imread(name);

  127. if (img.empty())

  128. {

  129. continue;

  130. }

  131. cv::Mat image;

  132. if (img.channels() != 1)

  133. {

  134. cvtColor(img, image, CV_BGR2GRAY);

  135. image.convertTo(image, CV_8UC1);

  136. }

  137. else{

  138. image = img;

  139. }

  140.  
  141. // Read Opencv Detection Bbx

  142. cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入

  143. cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);

  144. cv::equalizeHist(smallImg, smallImg); //equalizeHist提高图像的亮度和对比度

  145. // --Detection

  146. cascade.detectMultiScale(smallImg, faces,

  147. 1.1, 3, 0

  148. /*|CV_HAAR_FIND_BIGGEST_OBJECT

  149. |CV_HAAR_DO_ROUGH_SEARCH*/

  150. | CV_HAAR_SCALE_IMAGE

  151. ,

  152. cv::Size(30, 30));

  153. for (std::vector<cv::Rect>::iterator r = faces.begin(); r != faces.end(); r++)

  154. {

  155. cv::Rect face;

  156. face.x = int(r->x * scale);

  157. face.y = int(r->y * scale);

  158. face.width = int(r->width * scale);

  159. face.height = int(r->height * scale);

  160.  
  161. // 边界检查,左边界,上边界,右边界,下边界。

  162. /*face.x = face.x < 1 ? 1 : face.x;

  163. face.y = face.y < 1 ? 1 : face.y;

  164. face.width = (face.x + face.width) > image.cols ? (image.cols - face.x) : face.width;

  165. face.height = (face.y + face.height) > image.rows ? (image.rows - face.y) : face.height;*/

  166.  
  167. cv::Mat cropFace;

  168. cropFace = img(face);

  169. /*cv::moveWindow("cropface", 960 - cropFace.cols / 2, 540 - cropFace.rows / 2);

  170. cv::imshow("cropface", cropFace);

  171. cv::waitKey(100);

  172. cv::destroyWindow("cropface");*/

  173.  
  174. cropFaceAndImgPathName = make_pair(cropFace, name); //cropFaceAndImgPathName = std::pair<cv::Mat, std::string>(cropFace, name);

  175.  
  176. cropFaceAndImgPathNames.push_back(cropFaceAndImgPathName);

  177.  
  178. std::cout << '.';

  179. }

  180.  
  181. }

  182.  
  183. fdatabase.close();

  184.  
  185. std::cout << "]" << std::endl;

  186.  
  187. return cropFaceAndImgPathNames;

  188. }

  189.  
  190. bool matchFace(cv::Mat detectFace, cv::Mat dbFace)

  191. {

  192. IplImage* srcImg = cvCloneImage(&(IplImage)detectFace);

  193. IplImage* dstImg = cvCloneImage(&(IplImage)dbFace);

  194.  
  195. IplImage* src;

  196. IplImage* dst;

  197.  
  198. if (srcImg->nChannels != 1)

  199. {

  200. src = cvCreateImage(cvSize(srcImg->width, srcImg->height), srcImg->depth, 1);

  201. cvCvtColor(srcImg, src, CV_BGR2GRAY);

  202. }

  203.  
  204. if (dstImg->nChannels != 1)

  205. {

  206. dst = cvCreateImage(cvSize(dstImg->width, dstImg->height), dstImg->depth, 1);

  207. cvCvtColor(dstImg, dst, CV_BGR2GRAY);

  208. }

  209.  
  210. int histogramBins = 256;

  211. float histogramRange1[2] = { 0, 255 };

  212. float *histogramRange[1] = { &histogramRange1[0] };

  213. CvHistogram *Histogram1 = cvCreateHist(1, &histogramBins, CV_HIST_ARRAY, histogramRange);

  214. CvHistogram *Histogram2 = cvCreateHist(1, &histogramBins, CV_HIST_ARRAY, histogramRange);

  215.  
  216. cvCalcHist(&src, Histogram1);

  217. cvCalcHist(&dst, Histogram2);

  218.  
  219. cvNormalizeHist(Histogram1, 1);

  220. cvNormalizeHist(Histogram2, 1);

  221.  
  222.  
  223. // CV_COMP_CHISQR,CV_COMP_BHATTACHARYYA这两种都可以用来做直方图的比较,值越小,说明图形越相似

  224. //printf("CV_COMP_CHISQR : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR));

  225. //printf("CV_COMP_BHATTACHARYYA : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_BHATTACHARYYA));

  226.  
  227.  
  228. // CV_COMP_CORREL, CV_COMP_INTERSECT这两种直方图的比较,值越大,说明图形越相似

  229. //printf("CV_COMP_CORREL : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL));

  230. //printf("CV_COMP_INTERSECT : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_INTERSECT));

  231. double simility = cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR);

  232.  
  233. if (simility > 0.5)

  234. {

  235. return false;

  236. }

  237.  
  238. return true;

  239. }

  240.  
  241. void face_recognition(std::string recognitionPath, const std::string cascadeName)

  242. {

  243. bool isPreDeal = false;

  244. if (isPreDeal) //是否进行预处理

  245. {

  246. preDeal_original_img(recognitionPath, cascadeName);

  247. recognitionPath = "../camera_face/";

  248. }

  249.  
  250. //获取数据库中人脸图像

  251. std::string face_Database = "../face_database/Path_Images.txt";

  252. std::vector<std::pair<cv::Mat, std::string>> cropFaceAndImgPathNames;

  253. std::cout << "开始数据库中人脸数据的读取..." << std::endl;

  254. cropFaceAndImgPathNames = get_CropFace_And_ImgPathName(face_Database, cascadeName);

  255. std::cout << "结束数据库中人脸数据的读取。" << std::endl;

  256.  
  257. //开始人脸匹配

  258. std::ifstream frecognition;

  259. frecognition.open(recognitionPath);

  260. if (!frecognition)

  261. {

  262. std::cout << "Images path Error!" << std::endl;

  263. return;

  264. }

  265.  
  266. cv::CascadeClassifier cascade;

  267. cascade.load(cascadeName);

  268. if (cascade.empty())

  269. {

  270. std::cout << "Cascade path error!" << std::endl;

  271. return;

  272. }

  273.  
  274. double scale = 1.3;

  275. std::vector<cv::Rect> faces;

  276. cv::Mat gray;

  277. std::string name;

  278.  
  279. bool isExist = false; //数据库中是否存在该匹配文件

  280.  
  281. while (getline(frecognition, name)){

  282. if (name.empty())

  283. {

  284. continue;

  285. }

  286. name.erase(0, name.find_first_not_of(" \t"));

  287. name.erase(name.find_last_not_of(" \t") + 1);

  288.  
  289. // Read Image

  290. cv::Mat img = cv::imread(name);

  291. cv::Mat image;

  292. if (img.channels() != 1)

  293. {

  294. cvtColor(img, image, CV_BGR2GRAY);

  295. image.convertTo(image, CV_8UC1);

  296. }

  297. else{

  298. image = img;

  299. }

  300.  
  301. // Read Opencv Detection Bbx

  302. cv::Mat smallImg(cvRound(image.rows / scale), cvRound(image.cols / scale), CV_8UC1); //cvRound对double型数据进行四舍五入

  303. cv::resize(image, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);

  304. cv::equalizeHist(smallImg, smallImg); //equalizeHist提高图像的亮度和对比度

  305. // --Detection

  306. cascade.detectMultiScale(smallImg, faces,

  307. 1.1, 3, 0

  308. /*|CV_HAAR_FIND_BIGGEST_OBJECT

  309. |CV_HAAR_DO_ROUGH_SEARCH*/

  310. | CV_HAAR_SCALE_IMAGE

  311. ,

  312. cv::Size(30, 30));

  313. for (std::vector<cv::Rect>::iterator r = faces.begin(); r != faces.end(); r++)

  314. {

  315. cv::Rect face;

  316. face.x = int(r->x * scale);

  317. face.y = int(r->y * scale);

  318. face.width = int(r->width * scale);

  319. face.height = int(r->height * scale);

  320.  
  321. cv::Mat detectFace = img(face);

  322.  
  323. for (std::vector<std::pair<cv::Mat, std::string>>::iterator dbFace = cropFaceAndImgPathNames.begin(); dbFace != cropFaceAndImgPathNames.end(); dbFace++)

  324. {

  325. std::pair<cv::Mat, std::string> dbFaceImg = *dbFace;

  326. bool isMatch = matchFace(detectFace, dbFaceImg.first);

  327. if (isMatch){

  328. std::cout << name + " Matching " + dbFaceImg.second + " successful!" << std::endl;

  329. cv::imshow("detectFace", detectFace);

  330. cv::imshow("databaseFace", dbFaceImg.first);

  331. cv::waitKey(200);

  332. cv::destroyWindow("detectFace");

  333. cv::destroyWindow("databaseFace");

  334. isExist = true;

  335. }

  336. }

  337.  
  338. }

  339. }

  340.  
  341. if (!isExist)

  342. {

  343. std::cout << name + " Matching failed!" << std::endl;

  344. }

  345.  
  346. frecognition.close();

  347. }


还有最后的主函数:main.cpp

 
  1. #include "common.h"

  2. #include "face_detetion_img.h"

  3. #include "face_deteion_video.h"

  4. #include "face_detetion_camera.h"

  5. #include "face_recognition.h"

  6.  
  7.  
  8. int main(int argc, char ** argv)

  9. {

  10.  
  11. std::string cascadeFileName = "./../haarcascade_DataBase/haarcascade_frontalface_alt.xml";

  12.  
  13. //bool fileOrDir = isFileOrFolder(filePath);

  14.  
  15. if (argc < 2)

  16. {

  17. printf(help);

  18. }

  19. else if (strcmp(argv[1], "face_detetion_img") == 0)

  20. {

  21. std::string imgPath = "E:/1/ImagePath.txt";

  22. face_detetion_img(imgPath, cascadeFileName);

  23. }

  24. else if (strcmp(argv[1], "face_detetion_video") == 0)

  25. {

  26. std::string videoPath = "E:\\DeepLeaning\\codes\\FindFaceInVideo\\VGGFace\\chengshd\\IMG_3170.mp4";

  27. face_detetion_video(videoPath, cascadeFileName);

  28. }

  29. else if (strcmp(argv[1], "face_detetion_camera") == 0)

  30. {

  31. face_detetion_camera(cascadeFileName);

  32. }

  33. else if (strcmp(argv[1], "face_recognition") == 0)

  34. {

  35. std::string recognitionPath = "E:/camera/Path_Images.txt";

  36. face_recognition(recognitionPath, cascadeFileName);

  37. }

  38. else

  39. {

  40. printf(help);

  41. }

  42.  
  43. return 0;

  44. }

如果想使用代码,适当修改一下都是可以使用的。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值