#include #include #include #include #include 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(i, 0) << ", " << faces.at(i, 1) << "), " << "box width: " << faces.at(i, 2) << ", box height: " << faces.at(i, 3) << ", " << "score: " << faces.at(i, 14) << "\n"; // Draw bounding box rectangle(output, Rect2i(int(faces.at(i, 0)), int(faces.at(i, 1)), int(faces.at(i, 2)), int(faces.at(i, 3))), Scalar(0, 255, 0), thickness); // Draw landmarks circle(output, Point2i(int(faces.at(i, 4)), int(faces.at(i, 5))), 2, Scalar(255, 0, 0), thickness); circle(output, Point2i(int(faces.at(i, 6)), int(faces.at(i, 7))), 2, Scalar( 0, 0, 255), thickness); circle(output, Point2i(int(faces.at(i, 8)), int(faces.at(i, 9))), 2, Scalar( 0, 255, 0), thickness); circle(output, Point2i(int(faces.at(i, 10)), int(faces.at(i, 11))), 2, Scalar(255, 0, 255), thickness); circle(output, Point2i(int(faces.at(i, 12)), int(faces.at(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("model"); float scoreThreshold = parser.get("score_threshold"); float nmsThreshold = parser.get("nms_threshold"); int topK = parser.get("top_k"); bool save = parser.get("save"); bool vis = parser.get("vis"); // Initialize FaceDetectorYN Ptr detector = FaceDetectorYN::create(modelPath, "", Size(320, 320), scoreThreshold, nmsThreshold, topK); // If input is an image if (parser.has("input")) { String input = parser.get("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(); } } }