From b53e9cf0100685825ea76c5b0248159c57f9505b Mon Sep 17 00:00:00 2001 From: nxwhite-str Date: Wed, 22 Jun 2016 21:17:16 -0400 Subject: [PATCH] Add detection threshold adjustment to object detection python interface (#140) * Add cmake option to use external libjpeg on Mac OS * Add adjust_threshold to python object detector * Add cmake option to use external libjpeg on Mac OS * Add adjust_threshold to python object detector * Revert "Add cmake option to use external libjpeg on Mac OS" This reverts commit 01f7fd13ea3f2b519312900333f9b68847fd1633. * Update detector example to set adjust_threshold --- python_examples/face_detector.py | 4 +++- tools/python/src/object_detection.cpp | 4 ++-- tools/python/src/simple_object_detector_py.h | 16 +++++++++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/python_examples/face_detector.py b/python_examples/face_detector.py index 6b8723c9f..80d540386 100755 --- a/python_examples/face_detector.py +++ b/python_examples/face_detector.py @@ -71,11 +71,13 @@ for f in sys.argv[1:]: # Finally, if you really want to you can ask the detector to tell you the score # for each detection. The score is bigger for more confident detections. +# The third argument to run is an optional adjustment to the detection threshold, +# where a negative value will return more detections and a positive value fewer. # Also, the idx tells you which of the face sub-detectors matched. This can be # used to broadly identify faces in different orientations. if (len(sys.argv[1:]) > 0): img = io.imread(sys.argv[1]) - dets, scores, idx = detector.run(img, 1) + dets, scores, idx = detector.run(img, 1, -1) for i, d in enumerate(dets): print("Detection {}, score: {}, face_type:{}".format( d, scores[i], idx[i])) diff --git a/tools/python/src/object_detection.cpp b/tools/python/src/object_detection.cpp index 58a7ab297..82bc3956b 100644 --- a/tools/python/src/object_detection.cpp +++ b/tools/python/src/object_detection.cpp @@ -328,7 +328,7 @@ ensures \n\ detector. If you don't know how many times you want to upsample then \n\ don't provide a value for upsample_num_times and an appropriate \n\ default will be used.") - .def("run", run_rect_detector, (arg("image"), arg("upsample_num_times")=0), + .def("run", run_rect_detector, (arg("image"), arg("upsample_num_times")=0, arg("adjust_threshold")=0.0), "requires \n\ - image is a numpy ndarray containing either an 8bit grayscale or RGB \n\ image. \n\ @@ -350,7 +350,7 @@ ensures \n\ .def("__init__", make_constructor(&load_object_from_file), "Loads a simple_object_detector from a file that contains the output of the \n\ train_simple_object_detector() routine.") - .def("__call__", &type::run_detector1, (arg("image"), arg("upsample_num_times")), + .def("__call__", &type::run_detector1, (arg("image"), arg("upsample_num_times"), arg("adjust_threshold")=0.0), "requires \n\ - image is a numpy ndarray containing either an 8bit grayscale or RGB \n\ image. \n\ diff --git a/tools/python/src/simple_object_detector_py.h b/tools/python/src/simple_object_detector_py.h index 0bd103bff..e3ced42f0 100644 --- a/tools/python/src/simple_object_detector_py.h +++ b/tools/python/src/simple_object_detector_py.h @@ -37,6 +37,7 @@ namespace dlib dlib::simple_object_detector& detector, boost::python::object img, const unsigned int upsampling_amount, + const double adjust_threshold, std::vector& detection_confidences, std::vector& weight_indices ) @@ -51,7 +52,7 @@ namespace dlib array2d temp; if (upsampling_amount == 0) { - detector(numpy_gray_image(img), rect_detections, 0.0); + detector(numpy_gray_image(img), rect_detections, adjust_threshold); split_rect_detections(rect_detections, rectangles, detection_confidences, weight_indices); return rectangles; @@ -66,7 +67,7 @@ namespace dlib pyramid_up(temp); } - detector(temp, rect_detections, 0.0); + detector(temp, rect_detections, adjust_threshold); for (unsigned long i = 0; i < rect_detections.size(); ++i) rect_detections[i].rect = pyr.rect_down(rect_detections[i].rect, upsampling_amount); @@ -81,7 +82,7 @@ namespace dlib array2d temp; if (upsampling_amount == 0) { - detector(numpy_rgb_image(img), rect_detections, 0.0); + detector(numpy_rgb_image(img), rect_detections, adjust_threshold); split_rect_detections(rect_detections, rectangles, detection_confidences, weight_indices); return rectangles; @@ -96,7 +97,7 @@ namespace dlib pyramid_up(temp); } - detector(temp, rect_detections, 0.0); + detector(temp, rect_detections, adjust_threshold); for (unsigned long i = 0; i < rect_detections.size(); ++i) rect_detections[i].rect = pyr.rect_down(rect_detections[i].rect, upsampling_amount); @@ -116,19 +117,23 @@ namespace dlib dlib::simple_object_detector& detector, boost::python::object img, const unsigned int upsampling_amount + ) { std::vector detection_confidences; std::vector weight_indices; + const double adjust_threshold = 0.0; return run_detector_with_upscale1(detector, img, upsampling_amount, + adjust_threshold, detection_confidences, weight_indices); } inline boost::python::tuple run_rect_detector ( dlib::simple_object_detector& detector, boost::python::object img, - const unsigned int upsampling_amount) + const unsigned int upsampling_amount, + const double adjust_threshold) { boost::python::tuple t; @@ -137,6 +142,7 @@ namespace dlib std::vector rectangles; rectangles = run_detector_with_upscale1(detector, img, upsampling_amount, + adjust_threshold, detection_confidences, weight_indices); return boost::python::make_tuple(rectangles,