File size: 16,331 Bytes
9375c9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
// Copyright (C) 2012  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#undef DLIB_LOAD_IMAGE_DaTASET_ABSTRACT_Hh_
#ifdef DLIB_LOAD_IMAGE_DaTASET_ABSTRACT_Hh_

#include "image_dataset_metadata.h"
#include "../array/array_kernel_abstract.h"
#include <string>
#include <vector>
#include "../image_processing/full_object_detection_abstract.h"


namespace dlib
{

// ----------------------------------------------------------------------------------------

    class image_dataset_file
    {
        /*!
            WHAT THIS OBJECT REPRESENTS
                This object is a tool used to tell the load_image_dataset() functions which
                boxes and images to load from an XML based image dataset file.  By default,
                this object tells load_image_dataset() to load all images and object boxes.
        !*/

    public:
        image_dataset_file(
            const std::string& filename
        );
        /*!
            ensures
                - #get_filename() == filename
                - #should_skip_empty_images() == false
                - #get_selected_box_labels().size() == 0
                  This means that, initially, all boxes will be loaded.  Therefore, for all
                  possible boxes B we have:
                    - #should_load_box(B) == true
                - #box_area_thresh() == infinity
        !*/

        const std::string& get_filename(
        ) const;
        /*!
            ensures
                - returns the name of the XML image dataset metadata file given to this
                  object's constructor.
        !*/
        
        bool should_skip_empty_images(
        ) const;
        /*!
            ensures
                - returns true if we are supposed to skip images that don't have any
                  non-ignored boxes to load when loading an image dataset using
                  load_image_dataset().
        !*/

        image_dataset_file boxes_match_label(
            const std::string& label
        ) const;
        /*!
            ensures
                - returns a copy of *this that is identical in all respects to *this except
                  that label will be included in the labels set (i.e. the set returned by
                  get_selected_box_labels()).
        !*/

        const std::set<std::string>& get_selected_box_labels(
        ) const;
        /*!
            ensures
                - returns the set of box labels currently selected by the should_load_box()
                  method.  Note that if the set is empty then we select all boxes.
        !*/

        image_dataset_file skip_empty_images(
        ) const;
        /*!
            ensures
                - returns a copy of *this that is identical in all respects to *this except
                  that #should_skip_empty_images() == true.
        !*/

        bool should_boxes_have_parts(
        ) const; 
        /*!
            ensures
                - returns true if boxes must have some parts defined for them to be loaded.
        !*/

        image_dataset_file boxes_have_parts(
        ) const;
        /*!
            ensures
                - returns a copy of *this that is identical in all respects to *this except
                  that #should_boxes_have_parts() == true.
        !*/

        bool should_load_box (
            const image_dataset_metadata::box& box
        ) const;
        /*!
            ensures
                - returns true if we are supposed to load the given box from an image
                  dataset XML file.  In particular, if should_load_box() returns false then
                  the load_image_dataset() routines will not return the box at all, neither
                  in the ignore rectangles list or in the primary object_locations vector.
                  The behavior of this function is defined as follows:
                    - if (should_boxes_have_parts() && boxes.parts.size() == 0) then
                        - returns false
                    - else if (get_selected_box_labels().size() == 0) then
                        - returns true
                    - else if (get_selected_box_labels().count(box.label) != 0) then
                        - returns true
                    - else
                        - returns false
        !*/

        image_dataset_file shrink_big_images(
            double new_box_area_thresh = 150*150
        ) const;
        /*!
            ensures
                - returns a copy of *this that is identical in all respects to *this except
                  that #box_area_thresh() == new_box_area_thresh
        !*/

        double box_area_thresh(
        ) const;
        /*!
            ensures
                - If the smallest non-ignored rectangle in an image has an area greater
                  than box_area_thresh() then we will shrink the image until the area of
                  the box is about equal to box_area_thresh().  This is useful if you have
                  a dataset containing very high resolution images and you don't want to
                  load it in its native high resolution.  Setting the box_area_thresh()
                  allows you to control the resolution of the loaded images.
        !*/
    };

// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------

    template <
        typename array_type 
        >
    std::vector<std::vector<rectangle> > load_image_dataset (
        array_type& images,
        std::vector<std::vector<rectangle> >& object_locations,
        const image_dataset_file& source
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - This routine loads the images and their associated object boxes from the
              image metadata file indicated by source.get_filename().  This metadata file
              should be in the XML format used by the save_image_dataset_metadata() routine.
            - #images.size() == The number of images loaded from the metadata file.  This
              is all the images listed in the file unless source.should_skip_empty_images()
              is set to true.
            - #images.size() == #object_locations.size()
            - This routine is capable of loading any image format which can be read by the
              load_image() routine.
            - let IGNORED_RECTS denote the vector returned from this function.
            - IGNORED_RECTS.size() == #object_locations.size()
            - IGNORED_RECTS == a list of the rectangles which have the "ignore" flag set to
              true in the input XML file.
            - for all valid i:  
                - #images[i] == a copy of the i-th image from the dataset.
                - #object_locations[i] == a vector of all the rectangles associated with
                  #images[i].  These are the rectangles for which source.should_load_box()
                  returns true and are also not marked as "ignore" in the XML file.
                - IGNORED_RECTS[i] == A vector of all the rectangles associated with #images[i] 
                  that are marked as "ignore" but not discarded by source.should_load_box().
                - if (source.should_skip_empty_images() == true) then
                    - #object_locations[i].size() != 0
                      (i.e. we won't load images that don't end up having any object locations)
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename array_type 
        >
    std::vector<std::vector<rectangle> > load_image_dataset (
        array_type& images,
        std::vector<std::vector<rectangle> >& object_locations,
        const std::string& filename
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - performs: return load_image_dataset(images, object_locations, image_dataset_file(filename));
              (i.e. it ignores box labels and therefore loads all the boxes in the dataset)
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename array_type
        >
    void load_image_dataset (
        array_type& images,
        std::vector<std::vector<mmod_rect> >& object_locations,
        const image_dataset_file& source
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - This function has essentially the same behavior as the above
              load_image_dataset() routines, except here we output to a vector of
              mmod_rects instead of rectangles.  In this case, both ignore and non-ignore
              rectangles go into object_locations since mmod_rect has an ignore boolean
              field that records the ignored/non-ignored state of each rectangle.  We also store 
              a each box's string label into the mmod_rect::label field as well.
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename array_type 
        >
    void load_image_dataset (
        array_type& images,
        std::vector<std::vector<mmod_rect> >& object_locations,
        const std::string& filename
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - performs: load_image_dataset(images, object_locations, image_dataset_file(filename));
              (i.e. it ignores box labels and therefore loads all the boxes in the dataset)
    !*/

// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------

    template <
        typename array_type
        >
    std::vector<std::vector<rectangle> > load_image_dataset (
        array_type& images,
        std::vector<std::vector<full_object_detection> >& object_locations,
        const image_dataset_file& source,
        std::vector<std::string>& parts_list
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - This routine loads the images and their associated object locations from the
              image metadata file indicated by source.get_filename().  This metadata file
              should be in the XML format used by the save_image_dataset_metadata() routine.
            - The difference between this function and the version of load_image_dataset()
              defined above is that this version will also load object part information and
              thus fully populates the full_object_detection objects.
            - #images.size() == The number of images loaded from the metadata file.  This
              is all the images listed in the file unless source.should_skip_empty_images()
              is set to true.
            - #images.size() == #object_locations.size()
            - This routine is capable of loading any image format which can be read
              by the load_image() routine.
            - #parts_list == a vector that contains the list of object parts found in the
              input file and loaded into object_locations.
            - #parts_list is in lexicographic sorted order.
            - let IGNORED_RECTS denote the vector returned from this function.
            - IGNORED_RECTS.size() == #object_locations.size()
            - IGNORED_RECTS == a list of the rectangles which have the "ignore" flag set to
              true in the input XML file.
            - for all valid i:  
                - #images[i] == a copy of the i-th image from the dataset.
                - #object_locations[i] == a vector of all the rectangles associated with
                  #images[i].  These are the rectangles for which source.should_load_box()
                  returns true and are also not marked as "ignore" in the XML file.
                - IGNORED_RECTS[i] == A vector of all the rectangles associated with #images[i] 
                  that are marked as "ignore" but not discarded by source.should_load_box().
                - if (source.should_skip_empty_images() == true) then
                    - #object_locations[i].size() != 0
                      (i.e. we won't load images that don't end up having any object locations)
                - for all valid j:
                    - #object_locations[i][j].num_parts() == #parts_list.size()
                    - for all valid k:
                        - #object_locations[i][j].part(k) == the location of the part
                          with name #parts_list[k] or OBJECT_PART_NOT_PRESENT if the
                          part was not indicated for object #object_locations[i][j].
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename array_type 
        >
    std::vector<std::vector<rectangle> > load_image_dataset (
        array_type& images,
        std::vector<std::vector<full_object_detection> >& object_locations,
        const image_dataset_file& source 
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - performs: return load_image_dataset(images, object_locations, source, parts_list);
              (i.e. this function simply calls the above function and discards the output
              parts_list.  So it is just a convenience function you can call if you don't
              care about getting the parts list.)
    !*/

// ----------------------------------------------------------------------------------------

    template <
        typename array_type 
        >
    std::vector<std::vector<rectangle> > load_image_dataset (
        array_type& images,
        std::vector<std::vector<full_object_detection> >& object_locations,
        const std::string& filename
    );
    /*!
        requires
            - array_type == An array of images.  This is anything with an interface that
              looks like std::vector<some generic image type> where a "generic image" is
              anything that implements the generic image interface defined in
              dlib/image_processing/generic_image.h.
        ensures
            - performs: return load_image_dataset(images, object_locations, image_dataset_file(filename));
              (i.e. it ignores box labels and therefore loads all the boxes in the dataset)
    !*/

// ----------------------------------------------------------------------------------------

}

#endif // DLIB_LOAD_IMAGE_DaTASET_ABSTRACT_Hh_