1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include "ext_list.hpp"
6 #include "ext_base.hpp"
10 namespace InferenceEngine {
11 namespace Extensions {
14 class PriorBoxClusteredImpl: public ExtLayerBase {
16 explicit PriorBoxClusteredImpl(const CNNLayer* layer) {
18 if (layer->insData.size() != 2 || layer->outData.empty())
19 THROW_IE_EXCEPTION << "Incorrect number of input/output edges!";
21 if (layer->insData[0].lock()->dims.size() != 4 ||
22 layer->insData[1].lock()->dims.size() != 4)
23 THROW_IE_EXCEPTION << "PriorBoxClustered supports only 4D blobs!";
25 widths_ = layer->GetParamAsFloats("width", {});
26 heights_ = layer->GetParamAsFloats("height", {});
27 clip_ = layer->GetParamAsInt("clip");
28 variance_ = layer->GetParamAsFloats("variance", {});
29 img_h_ = layer->GetParamAsInt("img_h", 0);
30 img_w_ = layer->GetParamAsInt("img_w", 0);
31 step_ = layer->GetParamAsFloat("step", 0);
32 step_h_ = layer->GetParamAsFloat("step_h", 0);
33 step_w_ = layer->GetParamAsFloat("step_w", 0);
34 offset_ = layer->GetParamAsFloat("offset");
36 addConfig(layer, {{ConfLayout::PLN, true}, {ConfLayout::PLN, true}}, {{ConfLayout::PLN, true}});
37 } catch (InferenceEngine::details::InferenceEngineException &ex) {
42 StatusCode init(LayerConfig& config, ResponseDesc *resp) noexcept override {
46 StatusCode execute(std::vector<Blob::Ptr>& inputs, std::vector<Blob::Ptr>& outputs,
47 ResponseDesc *resp) noexcept override {
48 int num_priors_ = widths_.size();
50 if (variance_.empty())
51 variance_.push_back(0.1f);
54 const int layer_width = inputs[0]->getTensorDesc().getDims()[3];
55 const int layer_height = inputs[0]->getTensorDesc().getDims()[2];
57 int img_width = img_w_ == 0 ? inputs[1]->getTensorDesc().getDims()[3] : img_w_;
58 int img_height = img_h_ == 0 ? inputs[1]->getTensorDesc().getDims()[2] : img_h_;
60 float step_w = step_w_ == 0 ? step_ : step_w_;
61 float step_h = step_h_ == 0 ? step_ : step_h_;
62 if (step_w == 0 && step_h == 0) {
63 step_w = static_cast<float>(img_width) / layer_width;
64 step_h = static_cast<float>(img_height) / layer_height;
67 auto *top_data_0 = outputs[0]->buffer().as<float *>();
68 float *top_data_1 = top_data_0 + outputs[0]->getTensorDesc().getDims()[2];
69 int var_size = variance_.size();
71 for (int h = 0; h < layer_height; ++h) {
72 for (int w = 0; w < layer_width; ++w) {
73 float center_x = (w + offset_) * step_w;
74 float center_y = (h + offset_) * step_h;
76 for (int s = 0; s < num_priors_; ++s) {
77 float box_width = widths_[s];
78 float box_height = heights_[s];
80 float xmin = (center_x - box_width / 2.0f) / img_width;
81 float ymin = (center_y - box_height / 2.0f) / img_height;
82 float xmax = (center_x + box_width / 2.0f) / img_width;
83 float ymax = (center_y + box_height / 2.0f) / img_height;
86 xmin = std::min(std::max(xmin, 0.0f), 1.0f);
87 ymin = std::min(std::max(ymin, 0.0f), 1.0f);
88 xmax = std::min(std::max(xmax, 0.0f), 1.0f);
89 ymax = std::min(std::max(ymax, 0.0f), 1.0f);
92 top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 0] = xmin;
93 top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 1] = ymin;
94 top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 2] = xmax;
95 top_data_0[h * layer_width * num_priors_ * 4 + w * num_priors_ * 4 + s * 4 + 3] = ymax;
97 for (int j = 0; j < var_size; j++)
98 top_data_1[h * layer_width * num_priors_ * var_size + w * num_priors_ * var_size +
108 std::vector<float> widths_;
109 std::vector<float> heights_;
110 std::vector<float> variance_;
120 REG_FACTORY_FOR(ImplFactory<PriorBoxClusteredImpl>, PriorBoxClustered);
123 } // namespace Extensions
124 } // namespace InferenceEngine