face_detection_opencv_dnn.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <stdlib.h>
  5. #include <opencv2/core.hpp>
  6. #include <opencv2/imgproc.hpp>
  7. #include <opencv2/highgui.hpp>
  8. #include <opencv2/dnn.hpp>
  9. #include <boost/algorithm/string.hpp>
  10. using namespace cv;
  11. using namespace cv::dnn;
  12. using namespace std;
  13. const size_t inWidth = 300;
  14. const size_t inHeight = 300;
  15. const double inScaleFactor = 1.0;
  16. const float confidenceThreshold = 0.7;
  17. const cv::Scalar meanVal(104.0, 177.0, 123.0);
  18. const std::string caffeConfigFile = "models/deploy.prototxt";
  19. const std::string caffeWeightFile = "models/res10_300x300_ssd_iter_140000_fp16.caffemodel";
  20. const std::string tensorflowConfigFile = "models/opencv_face_detector.pbtxt";
  21. const std::string tensorflowWeightFile = "models/opencv_face_detector_uint8.pb";
  22. void detectFaceOpenCVDNN(Net net, Mat &frameOpenCVDNN, string framework)
  23. {
  24. int frameHeight = frameOpenCVDNN.rows;
  25. int frameWidth = frameOpenCVDNN.cols;
  26. cv::Mat inputBlob;
  27. if (framework == "caffe")
  28. inputBlob = cv::dnn::blobFromImage(frameOpenCVDNN, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, false, false);
  29. else
  30. inputBlob = cv::dnn::blobFromImage(frameOpenCVDNN, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, true, false);
  31. net.setInput(inputBlob, "data");
  32. cv::Mat detection = net.forward("detection_out");
  33. cv::Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());
  34. for(int i = 0; i < detectionMat.rows; i++)
  35. {
  36. float confidence = detectionMat.at<float>(i, 2);
  37. if(confidence > confidenceThreshold)
  38. {
  39. int x1 = static_cast<int>(detectionMat.at<float>(i, 3) * frameWidth);
  40. int y1 = static_cast<int>(detectionMat.at<float>(i, 4) * frameHeight);
  41. int x2 = static_cast<int>(detectionMat.at<float>(i, 5) * frameWidth);
  42. int y2 = static_cast<int>(detectionMat.at<float>(i, 6) * frameHeight);
  43. cv::rectangle(frameOpenCVDNN, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0),2, 4);
  44. }
  45. }
  46. }
  47. int main( int argc, const char** argv )
  48. {
  49. string videoFileName;
  50. string device;
  51. string framework;
  52. // Take arguments from command line
  53. if (argc == 4)
  54. {
  55. videoFileName = argv[1];
  56. device = argv[2];
  57. framework = argv[3];
  58. }
  59. else if (argc == 3)
  60. {
  61. videoFileName = argv[1];
  62. device = argv[2];
  63. framework = "caffe";
  64. }
  65. else if (argc == 2)
  66. {
  67. videoFileName = argv[1];
  68. device = "cpu";
  69. framework = "caffe";
  70. }
  71. else
  72. {
  73. videoFileName = "";
  74. device = "cpu";
  75. framework = "caffe";
  76. }
  77. boost::to_upper(device);
  78. cout << "Configuration:" << endl;
  79. cout << "Device - "<< device << endl;
  80. if (framework == "caffe")
  81. cout << "Network type - Caffe" << endl;
  82. else
  83. cout << "Network type - TensorFlow" << endl;
  84. if (videoFileName == "")
  85. cout << "No video found, using camera stream" << endl;
  86. else
  87. cout << "Video file - " << videoFileName << endl;
  88. Net net;
  89. if (framework == "caffe")
  90. net = cv::dnn::readNetFromCaffe(caffeConfigFile, caffeWeightFile);
  91. else
  92. net = cv::dnn::readNetFromTensorflow(tensorflowWeightFile, tensorflowConfigFile);
  93. #if (CV_MAJOR_VERSION >= 4)
  94. if (device == "CPU")
  95. {
  96. net.setPreferableBackend(DNN_TARGET_CPU);
  97. }
  98. else
  99. {
  100. net.setPreferableBackend(DNN_BACKEND_CUDA);
  101. net.setPreferableTarget(DNN_TARGET_CUDA);
  102. }
  103. #else
  104. // force CPU backend for OpenCV 3.x as CUDA backend is not supported there
  105. net.setPreferableBackend(DNN_BACKEND_DEFAULT);
  106. device = "cpu";
  107. #endif
  108. cv::VideoCapture source;
  109. if (videoFileName != "")
  110. source.open(videoFileName);
  111. else
  112. source.open(0, CAP_V4L);
  113. Mat frame;
  114. double tt_opencvDNN = 0;
  115. double fpsOpencvDNN = 0;
  116. while (true)
  117. {
  118. source >> frame;
  119. if (frame.empty())
  120. break;
  121. double t = cv::getTickCount();
  122. detectFaceOpenCVDNN(net, frame, framework);
  123. tt_opencvDNN = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
  124. fpsOpencvDNN = 1/tt_opencvDNN;
  125. putText(frame, format("OpenCV DNN %s FPS = %.2f", device.c_str(), fpsOpencvDNN), Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.3, Scalar(0, 0, 255), 4);
  126. imshow("OpenCV - DNN Face Detection", frame);
  127. int k = waitKey(5);
  128. if(k == 27)
  129. {
  130. destroyAllWindows();
  131. break;
  132. }
  133. }
  134. }