From 471b83ccd5e4ea86327774ce39d9607cf78010e0 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Mon, 6 May 2019 09:13:47 +0300 Subject: [PATCH] Modify paddings computation for SAME pad mode --- modules/dnn/src/layers/convolution_layer.cpp | 4 ++-- modules/dnn/src/layers/layers_common.cpp | 22 ++++++++++---------- modules/dnn/src/layers/layers_common.hpp | 5 ++--- modules/dnn/src/layers/pooling_layer.cpp | 2 +- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 3b298e616d..cfb93bb50a 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -125,7 +125,7 @@ public: inpShape.push_back(inputs[0].size[i]); outShape.push_back(outputs[0].size[i]); } - getConvPoolPaddings(inpShape, outShape, kernel_size, strides, padMode, dilations, pads_begin, pads_end); + getConvPoolPaddings(inpShape, kernel_size, strides, padMode, pads_begin, pads_end); if (pads_begin.size() == 2) { for (int i = 0; i < pads_begin.size(); i++) { if (pads_begin[i] != pads_end[i]) @@ -1257,7 +1257,7 @@ public: inpShape.push_back(inputs[0].size[i]); outShape.push_back(outputs[0].size[i]); } - getConvPoolPaddings(outShape, inpShape, kernel_size, strides, padMode, dilations, pads_begin, pads_end); + getConvPoolPaddings(outShape, kernel_size, strides, padMode, pads_begin, pads_end); if (pads_begin.size() == 2) { for (int i = 0; i < pads_begin.size(); i++) { if (pads_begin[i] != pads_end[i]) diff --git a/modules/dnn/src/layers/layers_common.cpp b/modules/dnn/src/layers/layers_common.cpp index 627f79c784..29d863d2ad 100644 --- a/modules/dnn/src/layers/layers_common.cpp +++ b/modules/dnn/src/layers/layers_common.cpp @@ -214,25 +214,25 @@ void getConvPoolOutParams(const std::vector& inp, const std::vector } } -void getConvPoolPaddings(const std::vector& inp, const std::vector& out, - const std::vector& kernel, const std::vector& strides, - const String &padMode, const std::vector& dilation, +void getConvPoolPaddings(const std::vector& inp, const std::vector& kernel, + const std::vector& strides, const String &padMode, std::vector& pads_begin, std::vector& pads_end) { - if (padMode == "VALID") + if (padMode == "SAME" || padMode == "VALID") { pads_begin.assign(kernel.size(), 0); pads_end.assign(kernel.size(), 0); } - else if (padMode == "SAME") + if (padMode == "SAME") { - CV_Assert_N(kernel.size() == dilation.size(), kernel.size() == strides.size(), - kernel.size() == inp.size(), kernel.size() == out.size()); - pads_begin.resize(kernel.size()); - pads_end.resize(kernel.size()); + CV_Assert_N(kernel.size() == strides.size(), kernel.size() == inp.size()); for (int i = 0; i < pads_begin.size(); i++) { - int pad = ((out[i] - 1) * strides[i] + dilation[i] * (kernel[i] - 1) + 1 - inp[i]) / 2; - pads_begin[i] = pads_end[i] = std::max(0, pad); + // There are test cases with stride > kernel. + if (strides[i] <= kernel[i]) + { + int pad = (kernel[i] - 1 - (inp[i] - 1 + strides[i]) % strides[i]) / 2; + pads_begin[i] = pads_end[i] = pad; + } } } } diff --git a/modules/dnn/src/layers/layers_common.hpp b/modules/dnn/src/layers/layers_common.hpp index fd1e430a54..26c1ce62d5 100644 --- a/modules/dnn/src/layers/layers_common.hpp +++ b/modules/dnn/src/layers/layers_common.hpp @@ -69,9 +69,8 @@ void getConvPoolOutParams(const std::vector& inp, const std::vector const std::vector& stride, const String &padMode, const std::vector& dilation, std::vector& out); - void getConvPoolPaddings(const std::vector& inp, const std::vector& out, - const std::vector& kernel, const std::vector& strides, - const String &padMode, const std::vector& dilation, + void getConvPoolPaddings(const std::vector& inp, const std::vector& kernel, + const std::vector& strides, const String &padMode, std::vector& pads_begin, std::vector& pads_end); } } diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index 78946b4b63..db5c84978a 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -143,7 +143,7 @@ public: kernel_size = std::vector(inp.begin(), inp.end()); } - getConvPoolPaddings(inp, out, kernel_size, strides, padMode, std::vector(kernel_size.size(), 1), pads_begin, pads_end); + getConvPoolPaddings(inp, kernel_size, strides, padMode, pads_begin, pads_end); if (pads_begin.size() == 2) { pad_t = pads_begin[0]; pad_l = pads_begin[1];