diff --git a/tools/python/src/basic.cpp b/tools/python/src/basic.cpp index 1b67653e8..d87a53cc3 100644 --- a/tools/python/src/basic.cpp +++ b/tools/python/src/basic.cpp @@ -4,6 +4,7 @@ #include #include #include +#include "opaque_types.h" #include #include @@ -12,22 +13,6 @@ using namespace std; using namespace dlib; namespace py = pybind11; -PYBIND11_MAKE_OPAQUE(std::vector); - -typedef std::vector> column_vectors; -PYBIND11_MAKE_OPAQUE(column_vectors); -PYBIND11_MAKE_OPAQUE(std::vector); - -typedef pair ulong_pair; -PYBIND11_MAKE_OPAQUE(ulong_pair); -PYBIND11_MAKE_OPAQUE(std::vector); -PYBIND11_MAKE_OPAQUE(std::vector>); - -typedef pair ulong_double_pair; -PYBIND11_MAKE_OPAQUE(ulong_double_pair); -PYBIND11_MAKE_OPAQUE(std::vector); -PYBIND11_MAKE_OPAQUE(std::vector>); -PYBIND11_MAKE_OPAQUE(std::vector > >); std::shared_ptr > array_from_object(py::object obj) { diff --git a/tools/python/src/cca.cpp b/tools/python/src/cca.cpp index 9c13f536a..dcf476522 100644 --- a/tools/python/src/cca.cpp +++ b/tools/python/src/cca.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include diff --git a/tools/python/src/cnn_face_detector.cpp b/tools/python/src/cnn_face_detector.cpp index 57690ed0f..94fd1e35a 100644 --- a/tools/python/src/cnn_face_detector.cpp +++ b/tools/python/src/cnn_face_detector.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2017 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include @@ -13,8 +14,6 @@ using namespace std; namespace py = pybind11; -PYBIND11_MAKE_OPAQUE(std::vector); -PYBIND11_MAKE_OPAQUE(std::vector >); class cnn_face_detection_model_v1 { diff --git a/tools/python/src/conversion.h b/tools/python/src/conversion.h index 8d39fdccf..9ab2360a0 100644 --- a/tools/python/src/conversion.h +++ b/tools/python/src/conversion.h @@ -3,6 +3,7 @@ #ifndef DLIB_PYTHON_CONVERSION_H__ #define DLIB_PYTHON_CONVERSION_H__ +#include "opaque_types.h" #include #include diff --git a/tools/python/src/correlation_tracker.cpp b/tools/python/src/correlation_tracker.cpp index cd06a482d..1b17ba54c 100644 --- a/tools/python/src/correlation_tracker.cpp +++ b/tools/python/src/correlation_tracker.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2014 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/decision_functions.cpp b/tools/python/src/decision_functions.cpp index 632f281d7..a93fe49b9 100644 --- a/tools/python/src/decision_functions.cpp +++ b/tools/python/src/decision_functions.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include "testing_results.h" #include diff --git a/tools/python/src/dlib.cpp b/tools/python/src/dlib.cpp index e07efee5c..ac6fea0db 100644 --- a/tools/python/src/dlib.cpp +++ b/tools/python/src/dlib.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2015 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/face_recognition.cpp b/tools/python/src/face_recognition.cpp index 8116c5828..8d5dee678 100644 --- a/tools/python/src/face_recognition.cpp +++ b/tools/python/src/face_recognition.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2017 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include @@ -17,7 +18,6 @@ using namespace std; namespace py = pybind11; -PYBIND11_MAKE_OPAQUE(std::vector); typedef matrix cv; diff --git a/tools/python/src/global_optimization.cpp b/tools/python/src/global_optimization.cpp index e5fecca96..400f78de6 100644 --- a/tools/python/src/global_optimization.cpp +++ b/tools/python/src/global_optimization.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2017 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/gui.cpp b/tools/python/src/gui.cpp index dabe9e2cb..418cfaae3 100644 --- a/tools/python/src/gui.cpp +++ b/tools/python/src/gui.cpp @@ -1,5 +1,6 @@ #ifndef DLIB_NO_GUI_SUPPORT +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/image.cpp b/tools/python/src/image.cpp index 3ac7ef33b..bd43ce5ab 100644 --- a/tools/python/src/image.cpp +++ b/tools/python/src/image.cpp @@ -1,3 +1,4 @@ +#include "opaque_types.h" #include #include "dlib/pixel.h" #include diff --git a/tools/python/src/image_dataset_metadata.cpp b/tools/python/src/image_dataset_metadata.cpp index 2f0459a2b..8f23ddd3f 100644 --- a/tools/python/src/image_dataset_metadata.cpp +++ b/tools/python/src/image_dataset_metadata.cpp @@ -1,10 +1,13 @@ // Copyright (C) 2018 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include +#include #include #include +#include namespace pybind11 { @@ -81,8 +84,6 @@ using namespace dlib::image_dataset_metadata; namespace py = pybind11; -typedef std::map parts_list_type; -PYBIND11_MAKE_OPAQUE(parts_list_type); dataset py_load_image_dataset_metadata( const std::string& filename @@ -103,6 +104,31 @@ std::shared_ptr> map_from_object(py::dict obj) return ret; } +// ---------------------------------------------------------------------------------------- + +image_dataset_metadata::dataset py_make_bounding_box_regression_training_data ( + const image_dataset_metadata::dataset& truth, + const py::object& detections +) +{ + try + { + // if detections is a std::vector then call like this. + return make_bounding_box_regression_training_data(truth, detections.cast>&>()); + } + catch (py::cast_error&) + { + // otherwise, detections should be a list of std::vectors. + py::list dets(detections); + std::vector> temp; + for (auto& d : dets) + temp.emplace_back(d.cast&>()); + return make_bounding_box_regression_training_data(truth, temp); + } +} + +// ---------------------------------------------------------------------------------------- + void bind_image_dataset_metadata(py::module &m_) { auto m = m_.def_submodule("image_dataset_metadata", "Routines and objects for working with dlib's image dataset metadata XML files."); @@ -194,6 +220,60 @@ void bind_image_dataset_metadata(py::module &m_) "Attempts to interpret filename as a file containing XML formatted data as produced " "by the save_image_dataset_metadata() function. The data is loaded and returned as a dlib.image_dataset_metadata.dataset object." ); + + m_.def("make_bounding_box_regression_training_data", &py_make_bounding_box_regression_training_data, + py::arg("truth"), py::arg("detections"), +"requires \n\ + - len(truth.images) == len(detections) \n\ + - detections == A dlib.rectangless object or a list of dlib.rectangles. \n\ +ensures \n\ + - Suppose you have an object detector that can roughly locate objects in an \n\ + image. This means your detector draws boxes around objects, but these are \n\ + *rough* boxes in the sense that they aren't positioned super accurately. For \n\ + instance, HOG based detectors usually have a stride of 8 pixels. So the \n\ + positional accuracy is going to be, at best, +/-8 pixels. \n\ + \n\ + If you want to get better positional accuracy one easy thing to do is train a \n\ + shape_predictor to give you the corners of the object. The \n\ + make_bounding_box_regression_training_data() routine helps you do this by \n\ + creating an appropriate training dataset. It does this by taking the dataset \n\ + you used to train your detector (the truth object), and combining that with \n\ + the output of your detector on each image in the training dataset (the \n\ + detections object). In particular, it will create a new annotated dataset \n\ + where each object box is one of the rectangles from detections and that \n\ + object has 4 part annotations, the corners of the truth rectangle \n\ + corresponding to that detection rectangle. You can then take the returned \n\ + dataset and train a shape_predictor on it. The resulting shape_predictor can \n\ + then be used to do bounding box regression. \n\ + - We assume that detections[i] contains object detections corresponding to \n\ + the image truth.images[i]." + /*! + requires + - len(truth.images) == len(detections) + - detections == A dlib.rectangless object or a list of dlib.rectangles. + ensures + - Suppose you have an object detector that can roughly locate objects in an + image. This means your detector draws boxes around objects, but these are + *rough* boxes in the sense that they aren't positioned super accurately. For + instance, HOG based detectors usually have a stride of 8 pixels. So the + positional accuracy is going to be, at best, +/-8 pixels. + + If you want to get better positional accuracy one easy thing to do is train a + shape_predictor to give you the corners of the object. The + make_bounding_box_regression_training_data() routine helps you do this by + creating an appropriate training dataset. It does this by taking the dataset + you used to train your detector (the truth object), and combining that with + the output of your detector on each image in the training dataset (the + detections object). In particular, it will create a new annotated dataset + where each object box is one of the rectangles from detections and that + object has 4 part annotations, the corners of the truth rectangle + corresponding to that detection rectangle. You can then take the returned + dataset and train a shape_predictor on it. The resulting shape_predictor can + then be used to do bounding box regression. + - We assume that detections[i] contains object detections corresponding to + the image truth.images[i]. + !*/ + ); } diff --git a/tools/python/src/matrix.cpp b/tools/python/src/matrix.cpp index 3ef1d8dce..a93544820 100644 --- a/tools/python/src/matrix.cpp +++ b/tools/python/src/matrix.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/numpy_returns.cpp b/tools/python/src/numpy_returns.cpp index 7fbeafa18..235816a78 100644 --- a/tools/python/src/numpy_returns.cpp +++ b/tools/python/src/numpy_returns.cpp @@ -1,3 +1,4 @@ +#include "opaque_types.h" #include #include "dlib/pixel.h" #include diff --git a/tools/python/src/numpy_returns_stub.cpp b/tools/python/src/numpy_returns_stub.cpp index 2807ee8dc..07d38ceac 100644 --- a/tools/python/src/numpy_returns_stub.cpp +++ b/tools/python/src/numpy_returns_stub.cpp @@ -1,3 +1,4 @@ +#include "opaque_types.h" #include #include "dlib/pixel.h" #include diff --git a/tools/python/src/object_detection.cpp b/tools/python/src/object_detection.cpp index ed0e3e299..bda570d7d 100644 --- a/tools/python/src/object_detection.cpp +++ b/tools/python/src/object_detection.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2015 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/opaque_types.h b/tools/python/src/opaque_types.h new file mode 100644 index 000000000..1a31c08df --- /dev/null +++ b/tools/python/src/opaque_types.h @@ -0,0 +1,55 @@ +// Copyright (C) 2017 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_PyTHON_OPAQUE_TYPES_H_ +#define DLIB_PyTHON_OPAQUE_TYPES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +// All uses of PYBIND11_MAKE_OPAQUE need to be in this common header to avoid ODR +// violations. +PYBIND11_MAKE_OPAQUE(std::vector); +PYBIND11_MAKE_OPAQUE(std::vector>); + +PYBIND11_MAKE_OPAQUE(std::vector); + + +typedef std::vector> column_vectors; +PYBIND11_MAKE_OPAQUE(column_vectors); +PYBIND11_MAKE_OPAQUE(std::vector); + +typedef std::pair ulong_pair; +PYBIND11_MAKE_OPAQUE(ulong_pair); +PYBIND11_MAKE_OPAQUE(std::vector); +PYBIND11_MAKE_OPAQUE(std::vector>); + +typedef std::pair ulong_double_pair; +PYBIND11_MAKE_OPAQUE(ulong_double_pair); +PYBIND11_MAKE_OPAQUE(std::vector); +PYBIND11_MAKE_OPAQUE(std::vector>); +PYBIND11_MAKE_OPAQUE(std::vector > >); + +PYBIND11_MAKE_OPAQUE(std::vector); +PYBIND11_MAKE_OPAQUE(std::vector >); +PYBIND11_MAKE_OPAQUE(std::vector); + +typedef std::map parts_list_type; +PYBIND11_MAKE_OPAQUE(parts_list_type); + +typedef std::vector>> ranking_pairs; +typedef std::vector > sparse_vect; +typedef std::vector > sparse_ranking_pairs; +PYBIND11_MAKE_OPAQUE(ranking_pairs); +PYBIND11_MAKE_OPAQUE(sparse_ranking_pairs); + + +PYBIND11_MAKE_OPAQUE(std::vector); + +#endif // DLIB_PyTHON_OPAQUE_TYPES_H_ + diff --git a/tools/python/src/other.cpp b/tools/python/src/other.cpp index 86157d18c..3e0149022 100644 --- a/tools/python/src/other.cpp +++ b/tools/python/src/other.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/rectangles.cpp b/tools/python/src/rectangles.cpp index b03e63b19..5b8021e7c 100644 --- a/tools/python/src/rectangles.cpp +++ b/tools/python/src/rectangles.cpp @@ -5,13 +5,13 @@ #include #include #include "indexing.h" +#include "opaque_types.h" using namespace dlib; using namespace std; namespace py = pybind11; -PYBIND11_MAKE_OPAQUE(std::vector); // ---------------------------------------------------------------------------------------- @@ -120,6 +120,7 @@ void bind_rectangles(py::module& m) .def(py::self != py::self) .def(py::pickle(&getstate, &setstate)); } + { typedef std::vector type; py::bind_vector(m, "rectangles", "An array of rectangle objects.") @@ -128,6 +129,15 @@ void bind_rectangles(py::module& m) .def("extend", extend_vector_with_python_list) .def(py::pickle(&getstate, &setstate)); } + + { + typedef std::vector> type; + py::bind_vector(m, "rectangless", "An array of arrays of rectangle objects.") + .def("clear", &type::clear) + .def("resize", resize) + .def("extend", extend_vector_with_python_list) + .def(py::pickle(&getstate, &setstate)); + } } // ---------------------------------------------------------------------------------------- diff --git a/tools/python/src/sequence_segmenter.cpp b/tools/python/src/sequence_segmenter.cpp index b20b48701..9fde1e771 100644 --- a/tools/python/src/sequence_segmenter.cpp +++ b/tools/python/src/sequence_segmenter.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/shape_predictor.cpp b/tools/python/src/shape_predictor.cpp index 4f4d08e29..efd58ce3b 100644 --- a/tools/python/src/shape_predictor.cpp +++ b/tools/python/src/shape_predictor.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2014 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/simple_object_detector_py.h b/tools/python/src/simple_object_detector_py.h index f728ae42c..0f950273d 100644 --- a/tools/python/src/simple_object_detector_py.h +++ b/tools/python/src/simple_object_detector_py.h @@ -3,6 +3,7 @@ #ifndef DLIB_SIMPLE_OBJECT_DETECTOR_PY_H__ #define DLIB_SIMPLE_OBJECT_DETECTOR_PY_H__ +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/svm_c_trainer.cpp b/tools/python/src/svm_c_trainer.cpp index f9bdfd6c7..7b592abe7 100644 --- a/tools/python/src/svm_c_trainer.cpp +++ b/tools/python/src/svm_c_trainer.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include "testing_results.h" #include diff --git a/tools/python/src/svm_rank_trainer.cpp b/tools/python/src/svm_rank_trainer.cpp index 43979b263..26cf3111a 100644 --- a/tools/python/src/svm_rank_trainer.cpp +++ b/tools/python/src/svm_rank_trainer.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include @@ -12,12 +13,7 @@ using namespace std; namespace py = pybind11; typedef matrix sample_type; -typedef std::vector > sparse_vect; -typedef std::vector > ranking_pairs; -typedef std::vector > sparse_ranking_pairs; -PYBIND11_MAKE_OPAQUE(ranking_pairs); -PYBIND11_MAKE_OPAQUE(sparse_ranking_pairs); // ---------------------------------------------------------------------------------------- diff --git a/tools/python/src/svm_struct.cpp b/tools/python/src/svm_struct.cpp index 118fbb19a..d8ebad957 100644 --- a/tools/python/src/svm_struct.cpp +++ b/tools/python/src/svm_struct.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include diff --git a/tools/python/src/vector.cpp b/tools/python/src/vector.cpp index cf85b2017..a9f81c65e 100644 --- a/tools/python/src/vector.cpp +++ b/tools/python/src/vector.cpp @@ -1,6 +1,7 @@ // Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. +#include "opaque_types.h" #include #include #include @@ -12,7 +13,6 @@ using namespace std; typedef matrix cv; -PYBIND11_MAKE_OPAQUE(std::vector); void cv_set_size(cv& m, long s) {