diff --git a/example/opencv_dnn/README.md b/example/opencv_dnn/README.md index f3c69df81..7f2b7128d 100644 --- a/example/opencv_dnn/README.md +++ b/example/opencv_dnn/README.md @@ -33,5 +33,6 @@ You can view the network architecture here[[netron]](https://netron.app/?url=htt ``` 2. Run the example: ```shell - ./detect /path/to/image /path/to/YuFaceDetectNet.onnx + ./detect-image /path/to/image /path/to/YuFaceDetectNet.onnx + ./detect-camera 0 /path/to/YuFaceDetectNet.onnx # '0' is your camera index. ``` \ No newline at end of file diff --git a/example/opencv_dnn/cpp/CMakeLists.txt b/example/opencv_dnn/cpp/CMakeLists.txt index 640a18c00..5b67a9b56 100644 --- a/example/opencv_dnn/cpp/CMakeLists.txt +++ b/example/opencv_dnn/cpp/CMakeLists.txt @@ -6,5 +6,8 @@ project(libfacedetection_opencvdnn) find_package(OpenCV 4.5.1 REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) -add_executable(detect detect.cpp priorbox.cpp utils.cpp) -target_link_libraries(detect ${OpenCV_LIBS}) +add_executable(detect-image detect-image.cpp priorbox.cpp utils.cpp) +target_link_libraries(detect-image ${OpenCV_LIBS}) + +add_executable(detect-camera detect-camera.cpp priorbox.cpp utils.cpp) +target_link_libraries(detect-camera ${OpenCV_LIBS}) diff --git a/example/opencv_dnn/cpp/detect-camera.cpp b/example/opencv_dnn/cpp/detect-camera.cpp new file mode 100644 index 000000000..faf10f656 --- /dev/null +++ b/example/opencv_dnn/cpp/detect-camera.cpp @@ -0,0 +1,95 @@ +#include +#include +#include + +#include "priorbox.hpp" +#include "utils.hpp" + +#include "opencv2/opencv.hpp" + +int main(int argc, char* argv[]) { + + if(argc != 3) + { + printf("Usage: %s \n", argv[0]); + return -1; + } + + // Load .onnx model using OpenCV's DNN module + cv::dnn::Net net = cv::dnn::readNet(argv[2]); + net.setPreferableBackend(cv::dnn::DNN_BACKEND_DEFAULT); + net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU); + + cv::VideoCapture cap; + cv::Mat im, blob; + cv::TickMeter cvtm; + cv::Size img_shape; + std::vector output_names = { "loc", "conf", "iou" }; + std::vector output_blobs; + + cv::String title = cv::String("Detection Results on") + cv::String(argv[1]); + + // Inference hyperparameters + float conf_thresh = 0.6; + float nms_thresh = 0.3; + int keep_top_k = 750; + // Result + bool vis = false; + + if( isdigit(argv[1][0])) + { + cap.open(argv[1][0]-'0'); + if(! cap.isOpened()) + { + std::cerr << "Cannot open the camera." << std::endl; + return 0; + } + } + + cap >> im; + img_shape = im.size(); + PriorBox pb(img_shape, img_shape); + std::vector dets; + + if( cap.isOpened()) + { + while(true) + { + cap >> im; + cvtm.start(); + + // Build blob + blob = cv::dnn::blobFromImage(im, 1.0, cv::Size(), cv::Scalar()); + + // Forward + net.setInput(blob); + net.forward(output_blobs, output_names); + + // Decode bboxes, landmarks and scores + dets = pb.decode(output_blobs[0], output_blobs[1], output_blobs[2], conf_thresh); + + // NMS + if (dets.size() > 1) { + nms(dets, nms_thresh); + if (dets.size() > keep_top_k) { dets.erase(dets.begin()+keep_top_k, dets.end()); } + } + else if (dets.size() < 1) { + std::cout << "No faces found." << std::endl; + } + + cvtm.stop(); + + std::string timeLabel = cv::format("Inference time: %.2f ms", cvtm.getTimeMilli()); + cv::putText(im, timeLabel, cv::Point(0, 15), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 1); + + draw(im, dets); + + cvtm.reset(); + cv::imshow(title, im); + if((cv::waitKey(1)& 0xFF) == 27) + break; + } + } + + return 0; +} \ No newline at end of file diff --git a/example/opencv_dnn/cpp/detect.cpp b/example/opencv_dnn/cpp/detect-image.cpp similarity index 100% rename from example/opencv_dnn/cpp/detect.cpp rename to example/opencv_dnn/cpp/detect-image.cpp