1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Copyright (C) 2017, Intel Corporation, all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
43 #include "../precomp.hpp"
44 #include "layers_common.hpp"
46 namespace cv { namespace dnn {
48 class NormalizeBBoxLayerImpl CV_FINAL : public NormalizeBBoxLayer
51 NormalizeBBoxLayerImpl(const LayerParams& params)
53 setParamsFrom(params);
54 pnorm = params.get<float>("p", 2);
55 epsilon = params.get<float>("eps", 1e-10f);
56 acrossSpatial = params.get<bool>("across_spatial", true);
60 bool getMemoryShapes(const std::vector<MatShape> &inputs,
61 const int requiredOutputs,
62 std::vector<MatShape> &outputs,
63 std::vector<MatShape> &internals) const CV_OVERRIDE
65 CV_Assert(inputs.size() == 1);
66 Layer::getMemoryShapes(inputs, requiredOutputs, outputs, internals);
67 internals.resize(1, inputs[0]);
68 internals[0][0] = 1; // Batch size.
73 bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_)
75 std::vector<UMat> inputs;
76 std::vector<UMat> outputs;
77 std::vector<UMat> internals;
79 inputs_.getUMatVector(inputs);
80 outputs_.getUMatVector(outputs);
81 internals_.getUMatVector(internals);
83 CV_Assert(inputs.size() == 1 && outputs.size() == 1);
84 CV_Assert(inputs[0].total() == outputs[0].total());
86 const UMat& inp0 = inputs[0];
87 UMat& buffer = internals[0];
88 size_t num = inp0.size[0];
89 size_t channels = inp0.size[1];
90 size_t channelSize = inp0.total() / (num * channels);
91 for (size_t i = 0; i < num; ++i)
93 MatShape s = shape(channels, channelSize);
94 UMat src = inputs[i].reshape(1, s.size(), &s[0]);
95 UMat dst = outputs[i].reshape(1, s.size(), &s[0]);
98 absdiff(src, cv::Scalar::all(0), abs_mat);
99 pow(abs_mat, pnorm, buffer);
103 // add eps to avoid overflow
104 float absSum = sum(buffer)[0] + epsilon;
105 float norm = pow(absSum, 1.0f / pnorm);
106 multiply(src, 1.0f / norm, dst);
111 reduce(buffer, norm, 0, REDUCE_SUM);
114 // compute inverted norm to call multiply instead divide
115 cv::pow(norm, -1.0f / pnorm, norm);
117 repeat(norm, channels, 1, buffer);
118 multiply(src, buffer, dst);
124 Mat scale = blobs[0];
125 if (scale.total() == 1)
128 multiply(dst, scale.at<float>(0, 0), dst);
132 // _scale: _channels x 1
133 CV_Assert(scale.total() == channels);
134 repeat(scale, 1, dst.cols, buffer);
135 multiply(dst, buffer, dst);
143 void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
146 CV_TRACE_ARG_VALUE(name, "name", name.c_str());
148 CV_OCL_RUN((preferableTarget == DNN_TARGET_OPENCL) &&
149 OCL_PERFORMANCE_CHECK(ocl::Device::getDefault().isIntel()),
150 forward_ocl(inputs_arr, outputs_arr, internals_arr))
152 Layer::forward_fallback(inputs_arr, outputs_arr, internals_arr);
155 void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
158 CV_TRACE_ARG_VALUE(name, "name", name.c_str());
160 CV_Assert(inputs.size() == 1 && outputs.size() == 1);
161 CV_Assert(inputs[0]->total() == outputs[0].total());
163 const Mat& inp0 = *inputs[0];
164 Mat& buffer = internals[0];
165 size_t num = inp0.size[0];
166 size_t channels = inp0.size[1];
167 size_t channelSize = inp0.total() / (num * channels);
168 for (size_t n = 0; n < num; ++n)
170 Mat src = Mat(channels, channelSize, CV_32F, (void*)inp0.ptr<float>(n));
171 Mat dst = Mat(channels, channelSize, CV_32F, (void*)outputs[0].ptr<float>(n));
173 cv::pow(abs(src), pnorm, buffer);
177 // add eps to avoid overflow
178 float absSum = sum(buffer)[0] + epsilon;
179 float norm = pow(absSum, 1.0f / pnorm);
180 multiply(src, 1.0f / norm, dst);
185 reduce(buffer, norm, 0, REDUCE_SUM);
188 // compute inverted norm to call multiply instead divide
189 cv::pow(norm, -1.0f / pnorm, norm);
191 repeat(norm, channels, 1, buffer);
192 multiply(src, buffer, dst);
198 Mat scale = blobs[0];
199 if (scale.total() == 1)
202 dst *= scale.at<float>(0, 0);
206 // _scale: _channels x 1
207 CV_Assert(scale.total() == channels);
208 repeat(scale, 1, dst.cols, buffer);
209 multiply(dst, buffer, dst);
217 Ptr<NormalizeBBoxLayer> NormalizeBBoxLayer::create(const LayerParams ¶ms)
219 return Ptr<NormalizeBBoxLayer>(new NormalizeBBoxLayerImpl(params));