Merge pull request #11711 from alalek:python_standalone
[platform/upstream/opencv.git] / modules / dnn / src / layers / resize_nearest_neighbor_layer.cpp
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.
4
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>
11
12 namespace cv { namespace dnn {
13
14 class ResizeNearestNeighborLayerImpl CV_FINAL : public ResizeNearestNeighborLayer
15 {
16 public:
17     ResizeNearestNeighborLayerImpl(const LayerParams& params)
18     {
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);
26         if (alignCorners)
27             CV_Error(Error::StsNotImplemented, "Nearest neighborhood resize with align_corners=true is not implemented");
28     }
29
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
34     {
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]);
41     }
42
43     virtual bool supportBackend(int backendId) CV_OVERRIDE
44     {
45         return backendId == DNN_BACKEND_OPENCV ||
46                backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
47     }
48
49     virtual void finalize(const std::vector<Mat*>& inputs, std::vector<Mat> &outputs) CV_OVERRIDE
50     {
51         if (!outWidth && !outHeight)
52         {
53             outHeight = outputs[0].size[2];
54             outWidth = outputs[0].size[3];
55         }
56     }
57
58     void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
59     {
60         CV_TRACE_FUNCTION();
61         CV_TRACE_ARG_VALUE(name, "name", name.c_str());
62
63         Layer::forward_fallback(inputs_arr, outputs_arr, internals_arr);
64     }
65
66     void forward(std::vector<Mat*> &inputs, std::vector<Mat> &outputs, std::vector<Mat> &internals) CV_OVERRIDE
67     {
68         CV_TRACE_FUNCTION();
69         CV_TRACE_ARG_VALUE(name, "name", name.c_str());
70
71         if (outHeight == inputs[0]->size[2] && outWidth == inputs[0]->size[3])
72             return;
73
74         Mat& inp = *inputs[0];
75         Mat& out = outputs[0];
76         for (size_t n = 0; n < inputs[0]->size[0]; ++n)
77         {
78             for (size_t ch = 0; ch < inputs[0]->size[1]; ++ch)
79             {
80                 resize(getPlane(inp, n, ch), getPlane(out, n, ch),
81                        Size(outWidth, outHeight), 0, 0, INTER_NEAREST);
82             }
83         }
84     }
85
86     virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >&) CV_OVERRIDE
87     {
88 #ifdef HAVE_INF_ENGINE
89         InferenceEngine::LayerParams lp;
90         lp.name = name;
91         lp.type = "Resample";
92         lp.precision = InferenceEngine::Precision::FP32;
93
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);
99
100         return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
101 #endif  // HAVE_INF_ENGINE
102         return Ptr<BackendNode>();
103     }
104
105 private:
106     int outWidth, outHeight, zoomFactor;
107     bool alignCorners;
108 };
109
110
111 Ptr<ResizeNearestNeighborLayer> ResizeNearestNeighborLayer::create(const LayerParams& params)
112 {
113     return Ptr<ResizeNearestNeighborLayer>(new ResizeNearestNeighborLayerImpl(params));
114 }
115
116 }  // namespace dnn
117 }  // namespace cv