simple_object_detector_py.h 10.5 KB
Newer Older
1
2
3
4
5
// Copyright (C) 2014  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#ifndef DLIB_SIMPLE_OBJECT_DETECTOR_PY_H__
#define DLIB_SIMPLE_OBJECT_DETECTOR_PY_H__

Davis King's avatar
Davis King committed
6
#include "opaque_types.h"
7
8
9
10
11
#include <dlib/python.h>
#include <dlib/matrix.h>
#include <dlib/geometry.h>
#include <dlib/image_processing/frontal_face_detector.h>

12
13
namespace py = pybind11;

14
15
16
17
namespace dlib
{
    typedef object_detector<scan_fhog_pyramid<pyramid_down<6> > > simple_object_detector;

18
19
20
21
    inline void split_rect_detections (
        std::vector<rect_detection>& rect_detections,
        std::vector<rectangle>& rectangles,
        std::vector<double>& detection_confidences,
22
        std::vector<unsigned long>& weight_indices
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    )
    {
        rectangles.clear();
        detection_confidences.clear();
        weight_indices.clear();

        for (unsigned long i = 0; i < rect_detections.size(); ++i)
        {
            rectangles.push_back(rect_detections[i].rect);
            detection_confidences.push_back(rect_detections[i].detection_confidence);
            weight_indices.push_back(rect_detections[i].weight_index);
        }
    }

Jack Culpepper's avatar
Jack Culpepper committed
37
38

    inline std::vector<dlib::rectangle> run_detector_with_upscale1 (
39
        dlib::simple_object_detector& detector,
40
        py::object img,
41
        const unsigned int upsampling_amount,
42
        const double adjust_threshold,
43
        std::vector<double>& detection_confidences,
44
        std::vector<unsigned long>& weight_indices
45
46
47
48
    )
    {
        pyramid_down<2> pyr;

49
50
51
        std::vector<rectangle> rectangles;
        std::vector<rect_detection> rect_detections;

52
53
54
55
56
        if (is_gray_python_image(img))
        {
            array2d<unsigned char> temp;
            if (upsampling_amount == 0)
            {
57
                detector(numpy_gray_image(img), rect_detections, adjust_threshold);
58
59
60
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);
                return rectangles;
61
62
63
64
65
66
67
68
69
70
71
            }
            else
            {
                pyramid_up(numpy_gray_image(img), temp, pyr);
                unsigned int levels = upsampling_amount-1;
                while (levels > 0)
                {
                    levels--;
                    pyramid_up(temp);
                }

72
                detector(temp, rect_detections, adjust_threshold);
73
74
75
76
77
78
79
                for (unsigned long i = 0; i < rect_detections.size(); ++i)
                    rect_detections[i].rect = pyr.rect_down(rect_detections[i].rect,
                                                            upsampling_amount);
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);

                return rectangles;
80
81
82
83
84
85
86
            }
        }
        else if (is_rgb_python_image(img))
        {
            array2d<rgb_pixel> temp;
            if (upsampling_amount == 0)
            {
87
                detector(numpy_rgb_image(img), rect_detections, adjust_threshold);
88
89
90
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);
                return rectangles;
91
92
93
94
95
96
97
98
99
100
101
            }
            else
            {
                pyramid_up(numpy_rgb_image(img), temp, pyr);
                unsigned int levels = upsampling_amount-1;
                while (levels > 0)
                {
                    levels--;
                    pyramid_up(temp);
                }

102
                detector(temp, rect_detections, adjust_threshold);
103
104
105
106
107
108
109
                for (unsigned long i = 0; i < rect_detections.size(); ++i)
                    rect_detections[i].rect = pyr.rect_down(rect_detections[i].rect,
                                                            upsampling_amount);
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);

                return rectangles;
110
111
112
113
114
115
116
117
            }
        }
        else
        {
            throw dlib::error("Unsupported image type, must be 8bit gray or RGB image.");
        }
    }

118
119
    inline std::vector<dlib::rectangle> run_detectors_with_upscale1 (
        std::vector<simple_object_detector >& detectors,
120
        py::object img,
121
122
123
        const unsigned int upsampling_amount,
        const double adjust_threshold,
        std::vector<double>& detection_confidences,
124
        std::vector<unsigned long>& weight_indices
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
    )
    {
        pyramid_down<2> pyr;

        std::vector<rectangle> rectangles;
        std::vector<rect_detection> rect_detections;

        if (is_gray_python_image(img))
        {
            array2d<unsigned char> temp;
            if (upsampling_amount == 0)
            {
                evaluate_detectors(detectors, numpy_gray_image(img), rect_detections, adjust_threshold);
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);
                return rectangles;
            }
            else
            {
                pyramid_up(numpy_gray_image(img), temp, pyr);
                unsigned int levels = upsampling_amount-1;
                while (levels > 0)
                {
                    levels--;
                    pyramid_up(temp);
                }

                evaluate_detectors(detectors, 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);
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);

                return rectangles;
            }
        }
        else if (is_rgb_python_image(img))
        {
            array2d<rgb_pixel> temp;
            if (upsampling_amount == 0)
            {
                evaluate_detectors(detectors, numpy_rgb_image(img), rect_detections, adjust_threshold);
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);
                return rectangles;
            }
            else
            {
                pyramid_up(numpy_rgb_image(img), temp, pyr);
                unsigned int levels = upsampling_amount-1;
                while (levels > 0)
                {
                    levels--;
                    pyramid_up(temp);
                }

                evaluate_detectors(detectors, 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);
                split_rect_detections(rect_detections, rectangles,
                                      detection_confidences, weight_indices);

                return rectangles;
            }
        }
        else
        {
            throw dlib::error("Unsupported image type, must be 8bit gray or RGB image.");
        }
    }

Jack Culpepper's avatar
Jack Culpepper committed
198
199
    inline std::vector<dlib::rectangle> run_detector_with_upscale2 (
        dlib::simple_object_detector& detector,
200
        py::object img,
Jack Culpepper's avatar
Jack Culpepper committed
201
        const unsigned int upsampling_amount
202

Jack Culpepper's avatar
Jack Culpepper committed
203
204
205
    )
    {
        std::vector<double> detection_confidences;
206
        std::vector<unsigned long> weight_indices;
207
        const double adjust_threshold = 0.0;
Jack Culpepper's avatar
Jack Culpepper committed
208
209

        return run_detector_with_upscale1(detector, img, upsampling_amount,
210
                                          adjust_threshold,
Jack Culpepper's avatar
Jack Culpepper committed
211
212
213
                                          detection_confidences, weight_indices);
    }

214
    inline py::tuple run_rect_detector (
Jack Culpepper's avatar
Jack Culpepper committed
215
        dlib::simple_object_detector& detector,
216
        py::object img,
217
218
        const unsigned int upsampling_amount,
        const double adjust_threshold)
219
    {
220
        py::tuple t;
221
222

        std::vector<double> detection_confidences;
223
        std::vector<unsigned long> weight_indices;
224
225
        std::vector<rectangle> rectangles;

Jack Culpepper's avatar
Jack Culpepper committed
226
        rectangles = run_detector_with_upscale1(detector, img, upsampling_amount,
227
                                                adjust_threshold,
Jack Culpepper's avatar
Jack Culpepper committed
228
                                                detection_confidences, weight_indices);
229

230
        return py::make_tuple(rectangles,
231
232
                              vector_to_python_list(detection_confidences), 
                              vector_to_python_list(weight_indices));
233
234
    }

235
236
237
    inline py::tuple run_multiple_rect_detectors (
        py::list& detectors,
        py::object img,
238
239
240
        const unsigned int upsampling_amount,
        const double adjust_threshold)
    {
241
        py::tuple t;
242
243
244
245
246
247

        std::vector<simple_object_detector > vector_detectors;
        const unsigned long num_detectors = len(detectors);
        // Now copy the data into dlib based objects.
        for (unsigned long i = 0; i < num_detectors; ++i)
        {
248
            vector_detectors.push_back(detectors[i].cast<simple_object_detector >());
249
        }
250

251
        std::vector<double> detection_confidences;
252
        std::vector<unsigned long> weight_indices;
253
254
255
256
257
258
        std::vector<rectangle> rectangles;

        rectangles = run_detectors_with_upscale1(vector_detectors, img, upsampling_amount,
                                                adjust_threshold,
                                                detection_confidences, weight_indices);

259
        return py::make_tuple(rectangles,
260
261
                              vector_to_python_list(detection_confidences),
                              vector_to_python_list(weight_indices));
262
263
264
265
    }



266
267
268
269
270
271
272
273
274
    struct simple_object_detector_py
    {
        simple_object_detector detector;
        unsigned int upsampling_amount;

        simple_object_detector_py() {}
        simple_object_detector_py(simple_object_detector& _detector, unsigned int _upsampling_amount) :
            detector(_detector), upsampling_amount(_upsampling_amount) {}

275
        std::vector<dlib::rectangle> run_detector1 (py::object img,
276
277
                                                    const unsigned int upsampling_amount_)
        {
Jack Culpepper's avatar
Jack Culpepper committed
278
            return run_detector_with_upscale2(detector, img, upsampling_amount_);
279
        }
280

281
        std::vector<dlib::rectangle> run_detector2 (py::object img)
282
        {
Jack Culpepper's avatar
Jack Culpepper committed
283
            return run_detector_with_upscale2(detector, img, upsampling_amount);
284
285
286
        }


287
288
289
290
    };
}

#endif // DLIB_SIMPLE_OBJECT_DETECTOR_PY_H__