1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
5 // Copyright (C) 2017, Intel Corporation, all rights reserved.
6 // Third party copyrights are property of their respective owners.
7 #include "../precomp.hpp"
8 #include "layers_common.hpp"
9 #include "../op_inf_engine.hpp"
10 #include <opencv2/imgproc.hpp>
12 namespace cv { namespace dnn {
14 class ResizeNearestNeighborLayerImpl CV_FINAL : public ResizeNearestNeighborLayer
17 ResizeNearestNeighborLayerImpl(const LayerParams& params)
19 setParamsFrom(params);
20 CV_Assert(params.has("width") && params.has("height") || params.has("zoom_factor"));
21 CV_Assert(!params.has("width") && !params.has("height") || !params.has("zoom_factor"));
22 outWidth = params.get<float>("width", 0);
23 outHeight = params.get<float>("height", 0);
24 zoomFactor = params.get<int>("zoom_factor", 1);
25 alignCorners = params.get<bool>("align_corners", false);
27 CV_Error(Error::StsNotImplemented, "Nearest neighborhood resize with align_corners=true is not implemented");
30 bool getMemoryShapes(const std::vector<MatShape> &inputs,
31 const int requiredOutputs,
32 std::vector<MatShape> &outputs,
33 std::vector<MatShape> &internals) const CV_OVERRIDE
35 CV_Assert(inputs.size() == 1, inputs[0].size() == 4);
36 outputs.resize(1, inputs[0]);
37 outputs[0][2] = outHeight > 0 ? outHeight : (outputs[0][2] * zoomFactor);
38 outputs[0][3] = outWidth > 0 ? outWidth : (outputs[0][3] * zoomFactor);
39 // We can work in-place (do nothing) if input shape == output shape.
40 return (outputs[0][2] == inputs[0][2]) && (outputs[0][3] == inputs[0][3]);
43 virtual bool supportBackend(int backendId) CV_OVERRIDE
45 return backendId == DNN_BACKEND_OPENCV ||
46 backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
49 virtual void finalize(const std::vector<Mat*>& inputs, std::vector<Mat> &outputs) CV_OVERRIDE
51 if (!outWidth && !outHeight)
53 outHeight = outputs[0].size[2];
54 outWidth = outputs[0].size[3];
58 void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
61 CV_TRACE_ARG_VALUE(name, "name", name.c_str());
63 Layer::forward_fallback(inputs_arr, outputs_arr, internals_arr);
66 void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
69 CV_TRACE_ARG_VALUE(name, "name", name.c_str());
71 if (outHeight == inputs[0]->size[2] && outWidth == inputs[0]->size[3])
74 Mat& inp = *inputs[0];
75 Mat& out = outputs[0];
76 for (size_t n = 0; n < inputs[0]->size[0]; ++n)
78 for (size_t ch = 0; ch < inputs[0]->size[1]; ++ch)
80 resize(getPlane(inp, n, ch), getPlane(out, n, ch),
81 Size(outWidth, outHeight), 0, 0, INTER_NEAREST);
86 virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >&) CV_OVERRIDE
88 #ifdef HAVE_INF_ENGINE
89 InferenceEngine::LayerParams lp;
92 lp.precision = InferenceEngine::Precision::FP32;
94 std::shared_ptr<InferenceEngine::CNNLayer> ieLayer(new InferenceEngine::CNNLayer(lp));
95 ieLayer->params["type"] = "caffe.ResampleParameter.NEAREST";
96 ieLayer->params["antialias"] = "0";
97 ieLayer->params["width"] = cv::format("%d", outWidth);
98 ieLayer->params["height"] = cv::format("%d", outHeight);
100 return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
101 #endif // HAVE_INF_ENGINE
102 return Ptr<BackendNode>();
106 int outWidth, outHeight, zoomFactor;
111 Ptr<ResizeNearestNeighborLayer> ResizeNearestNeighborLayer::create(const LayerParams& params)
113 return Ptr<ResizeNearestNeighborLayer>(new ResizeNearestNeighborLayerImpl(params));