Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / api / CPP / prior_box.hpp
1 /*
2 // Copyright (c) 2016 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 ///////////////////////////////////////////////////////////////////////////////////////////////////
18 #pragma once
19
20 #include <cmath>
21
22 #include "../C/prior_box.h"
23 #include "primitive.hpp"
24
25 namespace cldnn
26 {
27 /// @addtogroup cpp_api C++ API
28 /// @{
29 /// @addtogroup cpp_topology Network Topology
30 /// @{
31 /// @addtogroup cpp_primitives Primitives
32 /// @{
33
34 /// @brief Generates a set of default bounding boxes with different sizes and aspect ratios.
35 /// @details The prior-boxes are shared across all the images in a batch (since they have the same width and height).
36 /// First feature stores the mean of each prior coordinate. 
37 /// Second feature stores the variance of each prior coordinate.
38 struct prior_box : public primitive_base<prior_box, CLDNN_PRIMITIVE_DESC(prior_box)>
39 {
40     CLDNN_DECLARE_PRIMITIVE(prior_box)
41
42     /// @brief Constructs prior-box primitive.
43     /// @param id This primitive id.
44     /// @param input Input primitive id.
45     /// @param img_size Image width and height.
46     /// @param min_sizes Minimum box sizes in pixels.
47     /// @param max_sizes Maximum box sizes in pixels.
48     /// @param aspect_ratios Various of aspect ratios. Duplicate ratios will be ignored.
49     /// @param flip If true, will flip each aspect ratio. For example, if there is aspect ratio "r", aspect ratio "1.0/r" we will generated as well.
50     /// @param clip If true, will clip the prior so that it is within [0, 1].
51     /// @param variance Variance for adjusting the prior boxes.
52     /// @param step_width Step width.
53     /// @param step_height Step height.
54     /// @param offset Offset to the top left corner of each cell.
55     prior_box(
56         const primitive_id& id,
57         const primitive_id& input,
58         const tensor& img_size,
59         const std::vector<float>& min_sizes,
60         const std::vector<float>& max_sizes = {},
61         const std::vector<float>& aspect_ratios = {},
62         const bool flip = true,
63         const bool clip = false,
64         const std::vector<float>& variance = {},
65         const float step_width = 0.f,
66         const float step_height = 0.f,
67         const float offset = 0.5f,
68         const bool scale_all_sizes = true,
69         const padding& output_padding = padding()
70         )
71         : primitive_base(id, {input}, output_padding)
72         , img_size(img_size)
73         , min_sizes(min_sizes)
74         , max_sizes(max_sizes)
75         , flip(flip)
76         , clip(clip)
77         , step_width(step_width)
78         , step_height(step_height)
79         , offset(offset)
80         , scale_all_sizes(scale_all_sizes)
81     {
82         this->aspect_ratios.push_back(1.f);
83         for (auto new_aspect_ratio : aspect_ratios) {
84             bool already_exist = false;
85             for (auto aspect_ratio : this->aspect_ratios) {
86                 if (std::fabs(new_aspect_ratio - aspect_ratio) < 1e-6) {
87                     already_exist = true;
88                     break;
89                 }
90             }
91             if (!already_exist) {
92                 this->aspect_ratios.push_back(new_aspect_ratio);
93                 if (flip) {
94                     if (std::fabs(new_aspect_ratio) < std::numeric_limits<float>::epsilon()) {
95                         throw std::runtime_error("prior_box aspect ratio can't be zero!");
96                     }
97                     this->aspect_ratios.push_back(1.f / new_aspect_ratio);
98                 }
99             }
100         }
101         if (variance.size() > 1) {
102             for (size_t i = 0; i < variance.size(); ++i) {
103                 this->variance.push_back(variance[i]);
104             }
105         }
106         else if (variance.size() == 1) {
107             this->variance.push_back(variance[0]);
108         }
109         else {
110             // Set default to 0.1.
111             this->variance.push_back(0.1f);
112         }
113     }
114
115     /// @brief Constructs a copy from C API @CLDNN_PRIMITIVE_DESC{prior-box}
116     prior_box(const dto* dto)
117         : primitive_base(dto)
118         , img_size(dto->img_size)
119         , min_sizes(float_arr_to_vector(dto->min_sizes))
120         , max_sizes(float_arr_to_vector(dto->max_sizes))
121         , aspect_ratios(float_arr_to_vector(dto->aspect_ratios))
122         , flip(dto->flip != 0)
123         , clip(dto->clip != 0)
124         , variance(float_arr_to_vector(dto->variance))
125         , step_width(dto->step_width)
126         , step_height(dto->step_height)
127         , offset(dto->offset)
128         , scale_all_sizes(dto->scale_all_sizes != 0)
129     {}
130
131     /// @brief Image width and height.
132     tensor img_size;
133     /// @brief  Minimum box sizes in pixels.
134     std::vector<float> min_sizes;
135     /// @brief Maximum box sizes in pixels.
136     std::vector<float> max_sizes;
137     /// @brief Various of aspect ratios. Duplicate ratios will be ignored.
138     std::vector<float> aspect_ratios;
139     /// @brief If true, will flip each aspect ratio. For example, if there is aspect ratio "r", aspect ratio "1.0/r" we will generated as well.
140     bool flip;
141     /// @brief If true, will clip the prior so that it is within [0, 1].
142     bool clip;
143     /// @brief Variance for adjusting the prior boxes.
144     std::vector<float> variance;
145     /// @brief Step width.
146     float step_width;
147     /// @brief Step height.
148     float step_height;
149     /// @brief Offset to the top left corner of each cell.
150     float offset;
151     /// @broef If false, only first min_size is scaled by aspect_ratios
152     bool scale_all_sizes;
153
154 private:
155     void update_dto(dto& dto) const override
156     {
157         dto.img_size = img_size;
158         dto.min_sizes = float_vector_to_arr(min_sizes);
159         dto.max_sizes = float_vector_to_arr(max_sizes);
160         dto.aspect_ratios = float_vector_to_arr(aspect_ratios);
161         dto.flip = flip;
162         dto.clip = clip;
163         dto.variance = float_vector_to_arr(variance);
164         dto.step_width = step_width;
165         dto.step_height = step_height;
166         dto.offset = offset;
167         dto.scale_all_sizes = scale_all_sizes;
168     }
169
170     static cldnn_float_arr float_vector_to_arr(const std::vector<float>& stor)
171     {
172         return{ stor.data(), stor.size() };
173     }
174
175     static std::vector<float> float_arr_to_vector(const cldnn_float_arr& arr)
176     {
177         std::vector<float> result(arr.size);
178         for (size_t i = 0; i < arr.size; i++)
179         {
180             result[i] = arr.data[i];
181         }
182         return result;
183     }
184 };
185 /// @}
186 /// @}
187 /// @}
188 }