summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/image_processing/object_detector.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:20:02 +0000
commit58daab21cd043e1dc37024a7f99b396788372918 (patch)
tree96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /ml/dlib/dlib/image_processing/object_detector.h
parentReleasing debian version 1.43.2-1. (diff)
downloadnetdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz
netdata-58daab21cd043e1dc37024a7f99b396788372918.zip
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ml/dlib/dlib/image_processing/object_detector.h')
-rw-r--r--ml/dlib/dlib/image_processing/object_detector.h626
1 files changed, 626 insertions, 0 deletions
diff --git a/ml/dlib/dlib/image_processing/object_detector.h b/ml/dlib/dlib/image_processing/object_detector.h
new file mode 100644
index 000000000..9f78abd19
--- /dev/null
+++ b/ml/dlib/dlib/image_processing/object_detector.h
@@ -0,0 +1,626 @@
+// Copyright (C) 2011 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_OBJECT_DeTECTOR_Hh_
+#define DLIB_OBJECT_DeTECTOR_Hh_
+
+#include "object_detector_abstract.h"
+#include "../geometry.h"
+#include <vector>
+#include "box_overlap_testing.h"
+#include "full_object_detection.h"
+
+namespace dlib
+{
+
+// ----------------------------------------------------------------------------------------
+
+ struct rect_detection
+ {
+ double detection_confidence;
+ unsigned long weight_index;
+ rectangle rect;
+
+ bool operator<(const rect_detection& item) const { return detection_confidence < item.detection_confidence; }
+ };
+
+ struct full_detection
+ {
+ double detection_confidence;
+ unsigned long weight_index;
+ full_object_detection rect;
+
+ bool operator<(const full_detection& item) const { return detection_confidence < item.detection_confidence; }
+ };
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename image_scanner_type>
+ struct processed_weight_vector
+ {
+ processed_weight_vector(){}
+
+ typedef typename image_scanner_type::feature_vector_type feature_vector_type;
+
+ void init (
+ const image_scanner_type&
+ )
+ /*!
+ requires
+ - w has already been assigned its value. Note that the point of this
+ function is to allow an image scanner to overload the
+ processed_weight_vector template and provide some different kind of
+ object as the output of get_detect_argument(). For example, the
+ scan_fhog_pyramid object uses an overload that causes
+ get_detect_argument() to return the special fhog_filterbank object
+ instead of a feature_vector_type. This avoids needing to construct the
+ fhog_filterbank during each call to detect and therefore speeds up
+ detection.
+ !*/
+ {}
+
+ // return the first argument to image_scanner_type::detect()
+ const feature_vector_type& get_detect_argument() const { return w; }
+
+ feature_vector_type w;
+ };
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type_
+ >
+ class object_detector
+ {
+ public:
+ typedef image_scanner_type_ image_scanner_type;
+ typedef typename image_scanner_type::feature_vector_type feature_vector_type;
+
+ object_detector (
+ );
+
+ object_detector (
+ const object_detector& item
+ );
+
+ object_detector (
+ const image_scanner_type& scanner_,
+ const test_box_overlap& overlap_tester_,
+ const feature_vector_type& w_
+ );
+
+ object_detector (
+ const image_scanner_type& scanner_,
+ const test_box_overlap& overlap_tester_,
+ const std::vector<feature_vector_type>& w_
+ );
+
+ explicit object_detector (
+ const std::vector<object_detector>& detectors
+ );
+
+ unsigned long num_detectors (
+ ) const { return w.size(); }
+
+ const feature_vector_type& get_w (
+ unsigned long idx = 0
+ ) const { return w[idx].w; }
+
+ const processed_weight_vector<image_scanner_type>& get_processed_w (
+ unsigned long idx = 0
+ ) const { return w[idx]; }
+
+ const test_box_overlap& get_overlap_tester (
+ ) const;
+
+ const image_scanner_type& get_scanner (
+ ) const;
+
+ object_detector& operator= (
+ const object_detector& item
+ );
+
+ template <
+ typename image_type
+ >
+ std::vector<rectangle> operator() (
+ const image_type& img,
+ double adjust_threshold = 0
+ );
+
+ template <
+ typename image_type
+ >
+ void operator() (
+ const image_type& img,
+ std::vector<std::pair<double, rectangle> >& final_dets,
+ double adjust_threshold = 0
+ );
+
+ template <
+ typename image_type
+ >
+ void operator() (
+ const image_type& img,
+ std::vector<std::pair<double, full_object_detection> >& final_dets,
+ double adjust_threshold = 0
+ );
+
+ template <
+ typename image_type
+ >
+ void operator() (
+ const image_type& img,
+ std::vector<full_object_detection>& final_dets,
+ double adjust_threshold = 0
+ );
+
+ // These typedefs are here for backwards compatibility with previous versions of
+ // dlib.
+ typedef ::dlib::rect_detection rect_detection;
+ typedef ::dlib::full_detection full_detection;
+
+ template <
+ typename image_type
+ >
+ void operator() (
+ const image_type& img,
+ std::vector<rect_detection>& final_dets,
+ double adjust_threshold = 0
+ );
+
+ template <
+ typename image_type
+ >
+ void operator() (
+ const image_type& img,
+ std::vector<full_detection>& final_dets,
+ double adjust_threshold = 0
+ );
+
+ template <typename T>
+ friend void serialize (
+ const object_detector<T>& item,
+ std::ostream& out
+ );
+
+ template <typename T>
+ friend void deserialize (
+ object_detector<T>& item,
+ std::istream& in
+ );
+
+ private:
+
+ bool overlaps_any_box (
+ const std::vector<rect_detection>& rects,
+ const dlib::rectangle& rect
+ ) const
+ {
+ for (unsigned long i = 0; i < rects.size(); ++i)
+ {
+ if (boxes_overlap(rects[i].rect, rect))
+ return true;
+ }
+ return false;
+ }
+
+ test_box_overlap boxes_overlap;
+ std::vector<processed_weight_vector<image_scanner_type> > w;
+ image_scanner_type scanner;
+ };
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename T>
+ void serialize (
+ const object_detector<T>& item,
+ std::ostream& out
+ )
+ {
+ int version = 2;
+ serialize(version, out);
+
+ T scanner;
+ scanner.copy_configuration(item.scanner);
+ serialize(scanner, out);
+ serialize(item.boxes_overlap, out);
+ // serialize all the weight vectors
+ serialize(item.w.size(), out);
+ for (unsigned long i = 0; i < item.w.size(); ++i)
+ serialize(item.w[i].w, out);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <typename T>
+ void deserialize (
+ object_detector<T>& item,
+ std::istream& in
+ )
+ {
+ int version = 0;
+ deserialize(version, in);
+ if (version == 1)
+ {
+ deserialize(item.scanner, in);
+ item.w.resize(1);
+ deserialize(item.w[0].w, in);
+ item.w[0].init(item.scanner);
+ deserialize(item.boxes_overlap, in);
+ }
+ else if (version == 2)
+ {
+ deserialize(item.scanner, in);
+ deserialize(item.boxes_overlap, in);
+ unsigned long num_detectors = 0;
+ deserialize(num_detectors, in);
+ item.w.resize(num_detectors);
+ for (unsigned long i = 0; i < item.w.size(); ++i)
+ {
+ deserialize(item.w[i].w, in);
+ item.w[i].init(item.scanner);
+ }
+ }
+ else
+ {
+ throw serialization_error("Unexpected version encountered while deserializing a dlib::object_detector object.");
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+// object_detector member functions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ object_detector<image_scanner_type>::
+ object_detector (
+ )
+ {
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ object_detector<image_scanner_type>::
+ object_detector (
+ const object_detector& item
+ )
+ {
+ boxes_overlap = item.boxes_overlap;
+ w = item.w;
+ scanner.copy_configuration(item.scanner);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ object_detector<image_scanner_type>::
+ object_detector (
+ const image_scanner_type& scanner_,
+ const test_box_overlap& overlap_tester,
+ const feature_vector_type& w_
+ ) :
+ boxes_overlap(overlap_tester)
+ {
+ // make sure requires clause is not broken
+ DLIB_ASSERT(scanner_.get_num_detection_templates() > 0 &&
+ w_.size() == scanner_.get_num_dimensions() + 1,
+ "\t object_detector::object_detector(scanner_,overlap_tester,w_)"
+ << "\n\t Invalid inputs were given to this function "
+ << "\n\t scanner_.get_num_detection_templates(): " << scanner_.get_num_detection_templates()
+ << "\n\t w_.size(): " << w_.size()
+ << "\n\t scanner_.get_num_dimensions(): " << scanner_.get_num_dimensions()
+ << "\n\t this: " << this
+ );
+
+ scanner.copy_configuration(scanner_);
+ w.resize(1);
+ w[0].w = w_;
+ w[0].init(scanner);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ object_detector<image_scanner_type>::
+ object_detector (
+ const image_scanner_type& scanner_,
+ const test_box_overlap& overlap_tester,
+ const std::vector<feature_vector_type>& w_
+ ) :
+ boxes_overlap(overlap_tester)
+ {
+ // make sure requires clause is not broken
+ DLIB_CASSERT(scanner_.get_num_detection_templates() > 0 && w_.size() > 0,
+ "\t object_detector::object_detector(scanner_,overlap_tester,w_)"
+ << "\n\t Invalid inputs were given to this function "
+ << "\n\t scanner_.get_num_detection_templates(): " << scanner_.get_num_detection_templates()
+ << "\n\t w_.size(): " << w_.size()
+ << "\n\t this: " << this
+ );
+
+ for (unsigned long i = 0; i < w_.size(); ++i)
+ {
+ DLIB_CASSERT(w_[i].size() == scanner_.get_num_dimensions() + 1,
+ "\t object_detector::object_detector(scanner_,overlap_tester,w_)"
+ << "\n\t Invalid inputs were given to this function "
+ << "\n\t scanner_.get_num_detection_templates(): " << scanner_.get_num_detection_templates()
+ << "\n\t w_["<<i<<"].size(): " << w_[i].size()
+ << "\n\t scanner_.get_num_dimensions(): " << scanner_.get_num_dimensions()
+ << "\n\t this: " << this
+ );
+ }
+
+ scanner.copy_configuration(scanner_);
+ w.resize(w_.size());
+ for (unsigned long i = 0; i < w.size(); ++i)
+ {
+ w[i].w = w_[i];
+ w[i].init(scanner);
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ object_detector<image_scanner_type>::
+ object_detector (
+ const std::vector<object_detector>& detectors
+ )
+ {
+ DLIB_CASSERT(detectors.size() != 0,
+ "\t object_detector::object_detector(detectors)"
+ << "\n\t Invalid inputs were given to this function "
+ << "\n\t this: " << this
+ );
+ std::vector<feature_vector_type> weights;
+ weights.reserve(detectors.size());
+ for (unsigned long i = 0; i < detectors.size(); ++i)
+ {
+ for (unsigned long j = 0; j < detectors[i].num_detectors(); ++j)
+ weights.push_back(detectors[i].get_w(j));
+ }
+
+ *this = object_detector(detectors[0].get_scanner(), detectors[0].get_overlap_tester(), weights);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ object_detector<image_scanner_type>& object_detector<image_scanner_type>::
+ operator= (
+ const object_detector& item
+ )
+ {
+ if (this == &item)
+ return *this;
+
+ boxes_overlap = item.boxes_overlap;
+ w = item.w;
+ scanner.copy_configuration(item.scanner);
+ return *this;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ template <
+ typename image_type
+ >
+ void object_detector<image_scanner_type>::
+ operator() (
+ const image_type& img,
+ std::vector<rect_detection>& final_dets,
+ double adjust_threshold
+ )
+ {
+ scanner.load(img);
+ std::vector<std::pair<double, rectangle> > dets;
+ std::vector<rect_detection> dets_accum;
+ for (unsigned long i = 0; i < w.size(); ++i)
+ {
+ const double thresh = w[i].w(scanner.get_num_dimensions());
+ scanner.detect(w[i].get_detect_argument(), dets, thresh + adjust_threshold);
+ for (unsigned long j = 0; j < dets.size(); ++j)
+ {
+ rect_detection temp;
+ temp.detection_confidence = dets[j].first-thresh;
+ temp.weight_index = i;
+ temp.rect = dets[j].second;
+ dets_accum.push_back(temp);
+ }
+ }
+
+ // Do non-max suppression
+ final_dets.clear();
+ if (w.size() > 1)
+ std::sort(dets_accum.rbegin(), dets_accum.rend());
+ for (unsigned long i = 0; i < dets_accum.size(); ++i)
+ {
+ if (overlaps_any_box(final_dets, dets_accum[i].rect))
+ continue;
+
+ final_dets.push_back(dets_accum[i]);
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ template <
+ typename image_type
+ >
+ void object_detector<image_scanner_type>::
+ operator() (
+ const image_type& img,
+ std::vector<full_detection>& final_dets,
+ double adjust_threshold
+ )
+ {
+ std::vector<rect_detection> dets;
+ (*this)(img,dets,adjust_threshold);
+
+ final_dets.resize(dets.size());
+
+ // convert all the rectangle detections into full_object_detections.
+ for (unsigned long i = 0; i < dets.size(); ++i)
+ {
+ final_dets[i].detection_confidence = dets[i].detection_confidence;
+ final_dets[i].weight_index = dets[i].weight_index;
+ final_dets[i].rect = scanner.get_full_object_detection(dets[i].rect, w[dets[i].weight_index].w);
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ template <
+ typename image_type
+ >
+ std::vector<rectangle> object_detector<image_scanner_type>::
+ operator() (
+ const image_type& img,
+ double adjust_threshold
+ )
+ {
+ std::vector<rect_detection> dets;
+ (*this)(img,dets,adjust_threshold);
+
+ std::vector<rectangle> final_dets(dets.size());
+ for (unsigned long i = 0; i < dets.size(); ++i)
+ final_dets[i] = dets[i].rect;
+
+ return final_dets;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ template <
+ typename image_type
+ >
+ void object_detector<image_scanner_type>::
+ operator() (
+ const image_type& img,
+ std::vector<std::pair<double, rectangle> >& final_dets,
+ double adjust_threshold
+ )
+ {
+ std::vector<rect_detection> dets;
+ (*this)(img,dets,adjust_threshold);
+
+ final_dets.resize(dets.size());
+ for (unsigned long i = 0; i < dets.size(); ++i)
+ final_dets[i] = std::make_pair(dets[i].detection_confidence,dets[i].rect);
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ template <
+ typename image_type
+ >
+ void object_detector<image_scanner_type>::
+ operator() (
+ const image_type& img,
+ std::vector<std::pair<double, full_object_detection> >& final_dets,
+ double adjust_threshold
+ )
+ {
+ std::vector<rect_detection> dets;
+ (*this)(img,dets,adjust_threshold);
+
+ final_dets.clear();
+ final_dets.reserve(dets.size());
+
+ // convert all the rectangle detections into full_object_detections.
+ for (unsigned long i = 0; i < dets.size(); ++i)
+ {
+ final_dets.push_back(std::make_pair(dets[i].detection_confidence,
+ scanner.get_full_object_detection(dets[i].rect, w[dets[i].weight_index].w)));
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ template <
+ typename image_type
+ >
+ void object_detector<image_scanner_type>::
+ operator() (
+ const image_type& img,
+ std::vector<full_object_detection>& final_dets,
+ double adjust_threshold
+ )
+ {
+ std::vector<rect_detection> dets;
+ (*this)(img,dets,adjust_threshold);
+
+ final_dets.clear();
+ final_dets.reserve(dets.size());
+
+ // convert all the rectangle detections into full_object_detections.
+ for (unsigned long i = 0; i < dets.size(); ++i)
+ {
+ final_dets.push_back(scanner.get_full_object_detection(dets[i].rect, w[dets[i].weight_index].w));
+ }
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ const test_box_overlap& object_detector<image_scanner_type>::
+ get_overlap_tester (
+ ) const
+ {
+ return boxes_overlap;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename image_scanner_type
+ >
+ const image_scanner_type& object_detector<image_scanner_type>::
+ get_scanner (
+ ) const
+ {
+ return scanner;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_OBJECT_DeTECTOR_Hh_
+
+