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 #ifndef OPENCV_DNN_SRC_CUDA4DNN_PRIMITIVES_RESIZE_HPP 6 #define OPENCV_DNN_SRC_CUDA4DNN_PRIMITIVES_RESIZE_HPP 7 8 #include "../../op_cuda.hpp" 9 10 #include "../csl/stream.hpp" 11 12 #include "../kernels/resize.hpp" 13 14 #include <utility> 15 16 namespace cv { namespace dnn { namespace cuda4dnn { 17 18 enum class InterpolationType { 19 NEAREST_NEIGHBOUR, 20 BILINEAR 21 }; 22 23 struct ResizeConfiguration { 24 InterpolationType type; 25 bool align_corners; 26 bool half_pixel_centers; 27 }; 28 29 template <class T> 30 class ResizeOp final : public CUDABackendNode { 31 public: 32 using wrapper_type = GetCUDABackendWrapperType<T>; 33 ResizeOp(csl::Stream stream_,const ResizeConfiguration & config)34 ResizeOp(csl::Stream stream_, const ResizeConfiguration& config) 35 : stream(std::move(stream_)) 36 { 37 type = config.type; 38 align_corners = config.align_corners; 39 half_pixel_centers = config.half_pixel_centers; 40 } 41 forward(const std::vector<cv::Ptr<BackendWrapper>> & inputs,const std::vector<cv::Ptr<BackendWrapper>> & outputs,csl::Workspace & workspace)42 void forward( 43 const std::vector<cv::Ptr<BackendWrapper>>& inputs, 44 const std::vector<cv::Ptr<BackendWrapper>>& outputs, 45 csl::Workspace& workspace) override 46 { 47 // sometimes the target shape is taken from the second input; we don't use it however 48 CV_Assert((inputs.size() == 1 || inputs.size() == 2) && outputs.size() == 1); 49 50 auto input_wrapper = inputs[0].dynamicCast<wrapper_type>(); 51 auto input = input_wrapper->getView(); 52 53 auto output_wrapper = outputs[0].dynamicCast<wrapper_type>(); 54 auto output = output_wrapper->getSpan(); 55 56 const auto compute_scale = [this](std::size_t input_size, std::size_t output_size) { 57 return (align_corners && output_size > 1) ? 58 static_cast<float>(input_size - 1) / (output_size - 1) : 59 static_cast<float>(input_size) / output_size; 60 }; 61 62 auto out_height = output.get_axis_size(-2), out_width = output.get_axis_size(-1); 63 auto in_height = input.get_axis_size(-2), in_width = input.get_axis_size(-1); 64 float scale_height = compute_scale(in_height, out_height), 65 scale_width = compute_scale(in_width, out_width); 66 67 if (type == InterpolationType::NEAREST_NEIGHBOUR) 68 kernels::resize_nn<T>(stream, output, input, scale_height, scale_width, align_corners, half_pixel_centers); 69 else if (type == InterpolationType::BILINEAR) 70 kernels::resize_bilinear<T>(stream, output, input, scale_height, scale_width, half_pixel_centers); 71 } 72 73 private: 74 csl::Stream stream; 75 InterpolationType type; 76 bool align_corners, half_pixel_centers; 77 }; 78 79 }}} /* namespace cv::dnn::cuda4dnn */ 80 81 #endif /* OPENCV_DNN_SRC_CUDA4DNN_PRIMITIVES_RESIZE_HPP */ 82