Blame view

3rdparty/opencv-4.5.4/samples/dnn/face_detect.cpp 4.78 KB
f4334277   Hu Chunming   提交3rdparty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  #include <opencv2/dnn.hpp>
  #include <opencv2/imgproc.hpp>
  #include <opencv2/highgui.hpp>
  #include <opencv2/objdetect.hpp>
  
  #include <iostream>
  
  using namespace cv;
  using namespace std;
  
  static Mat visualize(Mat input, Mat faces, int thickness=2)
  {
      Mat output = input.clone();
      for (int i = 0; i < faces.rows; i++)
      {
          // Print results
          cout << "Face " << i
               << ", top-left coordinates: (" << faces.at<float>(i, 0) << ", " << faces.at<float>(i, 1) << "), "
               << "box width: " << faces.at<float>(i, 2)  << ", box height: " << faces.at<float>(i, 3) << ", "
               << "score: " << faces.at<float>(i, 14) << "\n";
  
          // Draw bounding box
          rectangle(output, Rect2i(int(faces.at<float>(i, 0)), int(faces.at<float>(i, 1)), int(faces.at<float>(i, 2)), int(faces.at<float>(i, 3))), Scalar(0, 255, 0), thickness);
          // Draw landmarks
          circle(output, Point2i(int(faces.at<float>(i, 4)),  int(faces.at<float>(i, 5))),  2, Scalar(255,   0,   0), thickness);
          circle(output, Point2i(int(faces.at<float>(i, 6)),  int(faces.at<float>(i, 7))),  2, Scalar(  0,   0, 255), thickness);
          circle(output, Point2i(int(faces.at<float>(i, 8)),  int(faces.at<float>(i, 9))),  2, Scalar(  0, 255,   0), thickness);
          circle(output, Point2i(int(faces.at<float>(i, 10)), int(faces.at<float>(i, 11))), 2, Scalar(255,   0, 255), thickness);
          circle(output, Point2i(int(faces.at<float>(i, 12)), int(faces.at<float>(i, 13))), 2, Scalar(  0, 255, 255), thickness);
      }
      return output;
  }
  
  int main(int argc, char ** argv)
  {
      CommandLineParser parser(argc, argv,
          "{help  h           |            | Print this message.}"
          "{input i           |            | Path to the input image. Omit for detecting on default camera.}"
          "{model m           | yunet.onnx | Path to the model. Download yunet.onnx in https://github.com/ShiqiYu/libfacedetection.train/tree/master/tasks/task1/onnx.}"
          "{score_threshold   | 0.9        | Filter out faces of score < score_threshold.}"
          "{nms_threshold     | 0.3        | Suppress bounding boxes of iou >= nms_threshold.}"
          "{top_k             | 5000       | Keep top_k bounding boxes before NMS.}"
          "{save  s           | false      | Set true to save results. This flag is invalid when using camera.}"
          "{vis   v           | true       | Set true to open a window for result visualization. This flag is invalid when using camera.}"
      );
      if (argc == 1 || parser.has("help"))
      {
          parser.printMessage();
          return -1;
      }
  
      String modelPath = parser.get<String>("model");
  
      float scoreThreshold = parser.get<float>("score_threshold");
      float nmsThreshold = parser.get<float>("nms_threshold");
      int topK = parser.get<int>("top_k");
  
      bool save = parser.get<bool>("save");
      bool vis = parser.get<bool>("vis");
  
      // Initialize FaceDetectorYN
      Ptr<FaceDetectorYN> detector = FaceDetectorYN::create(modelPath, "", Size(320, 320), scoreThreshold, nmsThreshold, topK);
  
      // If input is an image
      if (parser.has("input"))
      {
          String input = parser.get<String>("input");
          Mat image = imread(input);
  
          // Set input size before inference
          detector->setInputSize(image.size());
  
          // Inference
          Mat faces;
          detector->detect(image, faces);
  
          // Draw results on the input image
          Mat result = visualize(image, faces);
  
          // Save results if save is true
          if(save)
          {
              cout << "Results saved to result.jpg\n";
              imwrite("result.jpg", result);
          }
  
          // Visualize results
          if (vis)
          {
              namedWindow(input, WINDOW_AUTOSIZE);
              imshow(input, result);
              waitKey(0);
          }
      }
      else
      {
          int deviceId = 0;
          VideoCapture cap;
          cap.open(deviceId, CAP_ANY);
          int frameWidth = int(cap.get(CAP_PROP_FRAME_WIDTH));
          int frameHeight = int(cap.get(CAP_PROP_FRAME_HEIGHT));
          detector->setInputSize(Size(frameWidth, frameHeight));
  
          Mat frame;
          TickMeter tm;
          String msg = "FPS: ";
          while(waitKey(1) < 0) // Press any key to exit
          {
              // Get frame
              if (!cap.read(frame))
              {
                  cerr << "No frames grabbed!\n";
                  break;
              }
  
              // Inference
              Mat faces;
              tm.start();
              detector->detect(frame, faces);
              tm.stop();
  
              // Draw results on the input image
              Mat result = visualize(frame, faces);
              putText(result, msg + to_string(tm.getFPS()), Point(0, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0));
  
              // Visualize results
              imshow("Live", result);
  
              tm.reset();
          }
      }
  }