2 // Copyright (c) 2017-2019 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "proposal_inst.h"
18 #include "primitive_type_base.h"
19 #include "json_object.h"
27 static void generate_anchors(unsigned base_size,
28 const std::vector<float>& ratios,
29 const std::vector<float>& scales,
30 std::vector<proposal_inst::anchor>& anchors,
31 float coordinates_offset,
35 primitive_type_id proposal_type_id() {
36 static primitive_type_base<proposal> instance;
40 layout proposal_inst::calc_output_layout(proposal_node const& node) {
41 assert(static_cast<bool>(node.get_primitive()->output_data_type) == false &&
42 "Output data type forcing is not supported for proposal_node!");
43 auto desc = node.get_primitive();
44 layout input_layout = node.get_dependency(cls_scores_index).get_output_layout();
46 return layout(input_layout.data_type,
48 {input_layout.size.batch[0] * desc->post_nms_topn, CLDNN_ROI_VECTOR_SIZE, 1, 1});
51 static inline std::string stringify_vector(std::vector<float> v) {
56 for (size_t i = 0; i < v.size(); ++i) {
68 static std::string stringify_port(const program_node& p) {
69 std::stringstream res;
70 auto node_info = p.desc_to_json();
76 std::string proposal_inst::to_string(proposal_node const& node) {
77 auto desc = node.get_primitive();
78 auto node_info = node.desc_to_json();
79 auto scales_parm = desc->scales;
81 std::stringstream primitive_description;
83 auto swap_xy = desc->swap_xy ? "true" : "false";
84 auto initial_clip = desc->initial_clip ? "true" : "false";
85 auto round_ratios = desc->round_ratios ? "true" : "false";
86 auto shift_anchors = desc->shift_anchors ? "true" : "false";
87 auto clip_before_nms = desc->clip_before_nms ? "true" : "false";
88 auto clip_after_nms = desc->clip_after_nms ? "true" : "false";
89 auto for_deformable = desc->clip_after_nms ? "true" : "false";
91 json_composite proposal_info;
92 proposal_info.add("cls score", stringify_port(node.cls_score()));
93 proposal_info.add("box pred", stringify_port(node.bbox_pred()));
94 proposal_info.add("image info", stringify_port(node.image_info()));
96 json_composite params;
97 params.add("max proposals", desc->max_proposals);
98 params.add("iou threshold", desc->iou_threshold);
99 params.add("base bbox size", desc->base_bbox_size);
100 params.add("min bbox size", desc->min_bbox_size);
101 params.add("pre nms topn", desc->pre_nms_topn);
102 params.add("post nms topn", desc->post_nms_topn);
103 params.add("ratios", stringify_vector(desc->ratios));
104 params.add("ratios", stringify_vector(desc->ratios));
105 params.add("coordinates offset", desc->coordinates_offset);
106 params.add("box coordinate scale", desc->box_coordinate_scale);
107 params.add("box size scale", desc->box_size_scale);
108 params.add("swap xy", swap_xy);
109 params.add("initial clip", initial_clip);
110 params.add("round ratios", round_ratios);
111 params.add("shift anchors", shift_anchors);
112 params.add("clip_before_nms", clip_before_nms);
113 params.add("clip_after_nms", clip_after_nms);
114 params.add("for_deformable", for_deformable);
115 proposal_info.add("params", params);
117 node_info->add("proposal info", proposal_info);
118 node_info->dump(primitive_description);
120 return primitive_description.str();
123 proposal_inst::typed_primitive_inst(network_impl& network, proposal_node const& node) : parent(network, node) {
124 generate_anchors(argument.base_bbox_size,
128 argument.coordinates_offset,
129 argument.shift_anchors,
130 argument.round_ratios);
133 static void generate_anchors(unsigned int base_size,
134 const std::vector<float>& ratios,
135 const std::vector<float>& scales, // input
136 std::vector<proposal_inst::anchor>& anchors, // output
137 float coordinates_offset,
140 const float base_area = static_cast<float>(base_size * base_size);
141 const float half_base_size = base_size * 0.5f;
142 const float center = 0.5f * (base_size - coordinates_offset);
145 // enumerate all transformed boxes
146 for (size_t ratio = 0; ratio < ratios.size(); ++ratio) {
147 // transformed width & height for given ratio factors
151 ratio_w = std::roundf(std::sqrt(base_area / ratios[ratio]));
152 ratio_h = std::roundf(ratio_w * ratios[ratio]);
154 ratio_w = std::sqrt(base_area / ratios[ratio]);
155 ratio_h = ratio_w * ratios[ratio];
158 for (size_t scale = 0; scale < scales.size(); ++scale) {
159 proposal_inst::anchor anchor;
160 // transformed width & height for given scale factors
161 const float scale_w = 0.5f * (ratio_w * scales[scale] - coordinates_offset);
162 const float scale_h = 0.5f * (ratio_h * scales[scale] - coordinates_offset);
164 // (x1, y1, x2, y2) for transformed box
165 anchor.start_x = center - scale_w;
166 anchor.start_y = center - scale_h;
167 anchor.end_x = center + scale_w;
168 anchor.end_y = center + scale_h;
171 anchor.start_x -= half_base_size;
172 anchor.start_y -= half_base_size;
173 anchor.end_x -= half_base_size;
174 anchor.end_y -= half_base_size;
177 anchors.push_back(anchor);