@@ -57,47 +57,39 @@ std::string makeName(const std::string& str1, const std::string& str2)
57
57
}
58
58
59
59
bool getParameter (const LayerParams ¶ms, const std::string& nameBase, const std::string& nameAll,
60
- int ¶meterH, int ¶meterW , bool hasDefault = false , const int & defaultValue = 0 )
60
+ std::vector< size_t >& parameter , bool hasDefault = false , const std::vector< size_t > & defaultValue = std::vector< size_t >( 2 , 0 ) )
61
61
{
62
62
std::string nameH = makeName (nameBase, std::string (" _h" ));
63
63
std::string nameW = makeName (nameBase, std::string (" _w" ));
64
64
std::string nameAll_ = nameAll;
65
- if (nameAll_ == " " )
66
- {
65
+ if (nameAll_ == " " )
67
66
nameAll_ = nameBase;
68
- }
69
67
70
68
if (params.has (nameH) && params.has (nameW))
71
69
{
72
- parameterH = params.get <int >(nameH);
73
- parameterW = params.get <int >(nameW);
70
+ CV_Assert (params.get <int >(nameH) >= 0 && params.get <int >(nameW) >= 0 );
71
+ parameter.push_back (params.get <int >(nameH));
72
+ parameter.push_back (params.get <int >(nameW));
74
73
return true ;
75
74
}
76
75
else
77
76
{
78
77
if (params.has (nameAll_))
79
78
{
80
79
DictValue param = params.get (nameAll_);
81
- parameterH = param.get <int >(0 );
82
- if (param.size () == 1 )
83
- {
84
- parameterW = parameterH;
85
- }
86
- else if (param.size () == 2 )
87
- {
88
- parameterW = param.get <int >(1 );
89
- }
90
- else
91
- {
92
- return false ;
80
+ for (int i = 0 ; i < param.size (); i++) {
81
+ CV_Assert (param.get <int >(i) >= 0 );
82
+ parameter.push_back (param.get <int >(i));
93
83
}
84
+ if (parameter.size () == 1 )
85
+ parameter.resize (2 , parameter[0 ]);
94
86
return true ;
95
87
}
96
88
else
97
89
{
98
- if (hasDefault)
90
+ if (hasDefault)
99
91
{
100
- parameterH = parameterW = defaultValue;
92
+ parameter = defaultValue;
101
93
return true ;
102
94
}
103
95
else
@@ -108,46 +100,55 @@ bool getParameter(const LayerParams ¶ms, const std::string& nameBase, const
108
100
}
109
101
}
110
102
111
- void getKernelSize (const LayerParams ¶ms, int &kernelH, int &kernelW )
103
+ void getKernelSize (const LayerParams ¶ms, std::vector< size_t >& kernel )
112
104
{
113
- if (!util::getParameter (params, " kernel" , " kernel_size" , kernelH, kernelW))
114
- {
105
+ if (!util::getParameter (params, " kernel" , " kernel_size" , kernel))
115
106
CV_Error (cv::Error::StsBadArg, " kernel_size (or kernel_h and kernel_w) not specified" );
116
- }
117
107
118
- CV_Assert (kernelH > 0 && kernelW > 0 );
108
+ for (int i = 0 ; i < kernel.size (); i++)
109
+ CV_Assert (kernel[i] > 0 );
119
110
}
120
111
121
- void getStrideAndPadding (const LayerParams ¶ms, int &padT, int &padL, int &padB, int &padR, int &strideH, int &strideW, cv::String& padMode)
112
+ void getStrideAndPadding (const LayerParams ¶ms, std::vector<size_t >& pads_begin, std::vector<size_t >& pads_end,
113
+ std::vector<size_t >& strides, cv::String& padMode, size_t kernel_size = 2 )
122
114
{
123
115
if (params.has (" pad_l" ) && params.has (" pad_t" ) && params.has (" pad_r" ) && params.has (" pad_b" )) {
124
- padT = params.get <int >(" pad_t" );
125
- padL = params.get <int >(" pad_l" );
126
- padB = params.get <int >(" pad_b" );
127
- padR = params.get <int >(" pad_r" );
116
+ CV_Assert (params.get <int >(" pad_t" ) >= 0 && params.get <int >(" pad_l" ) >= 0 &&
117
+ params.get <int >(" pad_b" ) >= 0 && params.get <int >(" pad_r" ) >= 0 );
118
+ pads_begin.push_back (params.get <int >(" pad_t" ));
119
+ pads_begin.push_back (params.get <int >(" pad_l" ));
120
+ pads_end.push_back (params.get <int >(" pad_b" ));
121
+ pads_end.push_back (params.get <int >(" pad_r" ));
128
122
}
129
123
else {
130
- util::getParameter (params, " pad" , " pad" , padT, padL, true , 0 );
131
- padB = padT;
132
- padR = padL;
124
+ util::getParameter (params, " pad" , " pad" , pads_begin, true , std::vector<size_t >(kernel_size, 0 ));
125
+ if (pads_begin.size () < 4 )
126
+ pads_end = pads_begin;
127
+ else
128
+ {
129
+ pads_end = std::vector<size_t >(pads_begin.begin () + pads_begin.size () / 2 , pads_begin.end ());
130
+ pads_begin.resize (pads_begin.size () / 2 );
131
+ }
132
+ CV_Assert (pads_begin.size () == pads_end.size ());
133
133
}
134
- util::getParameter (params, " stride" , " stride" , strideH, strideW, true , 1 );
134
+ util::getParameter (params, " stride" , " stride" , strides, true , std::vector< size_t >(kernel_size , 1 ) );
135
135
136
136
padMode = " " ;
137
137
if (params.has (" pad_mode" ))
138
138
{
139
139
padMode = params.get <String>(" pad_mode" );
140
140
}
141
141
142
- CV_Assert (padT >= 0 && padL >= 0 && padB >= 0 && padR >= 0 && strideH > 0 && strideW > 0 );
142
+ for (int i = 0 ; i < strides.size (); i++)
143
+ CV_Assert (strides[i] > 0 );
143
144
}
144
145
}
145
146
146
-
147
- void getPoolingKernelParams ( const LayerParams ¶ms, int &kernelH, int &kernelW, bool &globalPooling ,
148
- int &padT, int &padL, int &padB, int &padR, int &strideH, int &strideW , cv::String &padMode)
147
+ void getPoolingKernelParams ( const LayerParams ¶ms, std::vector< size_t >& kernel, bool &globalPooling,
148
+ std::vector< size_t >& pads_begin, std::vector< size_t >& pads_end ,
149
+ std::vector< size_t >& strides , cv::String &padMode)
149
150
{
150
- util::getStrideAndPadding (params, padT, padL, padB, padR, strideH, strideW , padMode);
151
+ util::getStrideAndPadding (params, pads_begin, pads_end, strides , padMode);
151
152
152
153
globalPooling = params.has (" global_pooling" ) &&
153
154
params.get <bool >(" global_pooling" );
@@ -158,25 +159,30 @@ void getPoolingKernelParams(const LayerParams ¶ms, int &kernelH, int &kernel
158
159
{
159
160
CV_Error (cv::Error::StsBadArg, " In global_pooling mode, kernel_size (or kernel_h and kernel_w) cannot be specified" );
160
161
}
161
- if (padT != 0 || padL != 0 || padB != 0 || padR != 0 || strideH != 1 || strideW != 1 )
162
- {
163
- CV_Error (cv::Error::StsBadArg, " In global_pooling mode, pads must be = 0, and stride_h and stride_w must be = 1" );
162
+ for (int i = 0 ; i < pads_begin.size (); i++) {
163
+ if (pads_begin[i] != 0 || pads_end[i] != 0 )
164
+ CV_Error (cv::Error::StsBadArg, " In global_pooling mode, pads must be = 0" );
165
+ }
166
+ for (int i = 0 ; i < strides.size (); i++) {
167
+ if (strides[i] != 1 )
168
+ CV_Error (cv::Error::StsBadArg, " In global_pooling mode, strides must be = 1" );
164
169
}
165
170
}
166
171
else
167
172
{
168
- util::getKernelSize (params, kernelH, kernelW );
173
+ util::getKernelSize (params, kernel );
169
174
}
170
175
}
171
176
172
- void getConvolutionKernelParams (const LayerParams ¶ms, int &kernelH, int &kernelW, int &padT, int &padL, int &padB, int &padR ,
173
- int &strideH, int &strideW, int &dilationH, int &dilationW , cv::String &padMode)
177
+ void getConvolutionKernelParams (const LayerParams ¶ms, std::vector< size_t >& kernel, std::vector< size_t >& pads_begin ,
178
+ std::vector< size_t >& pads_end, std::vector< size_t >& strides, std::vector< size_t >& dilations , cv::String &padMode)
174
179
{
175
- util::getKernelSize (params, kernelH, kernelW );
176
- util::getStrideAndPadding (params, padT, padL, padB, padR, strideH, strideW, padMode );
177
- util::getParameter (params, " dilation" , " dilation" , dilationH, dilationW, true , 1 );
180
+ util::getKernelSize (params, kernel );
181
+ util::getStrideAndPadding (params, pads_begin, pads_end, strides, padMode, kernel. size () );
182
+ util::getParameter (params, " dilation" , " dilation" , dilations, true , std::vector< size_t >(kernel. size () , 1 ) );
178
183
179
- CV_Assert (dilationH > 0 && dilationW > 0 );
184
+ for (int i = 0 ; i < dilations.size (); i++)
185
+ CV_Assert (dilations[i] > 0 );
180
186
}
181
187
182
188
// From TensorFlow code:
@@ -188,42 +194,46 @@ void getConvolutionKernelParams(const LayerParams ¶ms, int &kernelH, int &ke
188
194
// We pad Pr/2 on the left and Pr - Pr/2 on the right, Pc/2 on the top
189
195
// and Pc - Pc/2 on the bottom. When Pr or Pc is odd, this means
190
196
// we pad more on the right and bottom than on the top and left.
191
- void getConvPoolOutParams (const Size & inp, const Size & kernel,
192
- const Size & stride, const String &padMode,
193
- const Size & dilation, Size & out)
197
+ void getConvPoolOutParams (const std::vector< int > & inp, const std::vector< size_t >& kernel,
198
+ const std::vector< size_t >& stride, const String &padMode,
199
+ const std::vector< size_t >& dilation, std::vector< int > & out)
194
200
{
195
201
if (padMode == " VALID" )
196
202
{
197
- out. height = (inp. height - (dilation. height * (kernel. height - 1 ) + 1 ) + stride. height ) / stride. height ;
198
- out. width = ( inp. width - ( dilation. width * (kernel. width - 1 ) + 1 ) + stride. width ) / stride. width ;
203
+ for ( int i = 0 ; i < inp. size (); i++)
204
+ out. push_back (( inp[i] - dilation[i] * (kernel[i] - 1 ) - 1 + stride[i] ) / stride[i]) ;
199
205
}
200
206
else if (padMode == " SAME" )
201
207
{
202
- out. height = (inp. height - 1 + stride. height ) / stride. height ;
203
- out. width = ( inp. width - 1 + stride. width ) / stride. width ;
208
+ for ( int i = 0 ; i < inp. size (); i++)
209
+ out. push_back (( inp[i] - 1 + stride[i] ) / stride[i]) ;
204
210
}
205
211
else
206
212
{
207
213
CV_Error (Error::StsError, " Unsupported padding mode" );
208
214
}
209
215
}
210
216
211
- void getConvPoolPaddings (const Size& inp, const Size& out,
212
- const Size &kernel, const Size &stride,
213
- const String &padMode, const Size &dilation, int &padT, int &padL, int &padB, int &padR)
217
+ void getConvPoolPaddings (const std::vector<int >& inp, const std::vector<int >& out,
218
+ const std::vector<size_t >& kernel, const std::vector<size_t >& strides,
219
+ const String &padMode, const std::vector<size_t >& dilation,
220
+ std::vector<size_t >& pads_begin, std::vector<size_t >& pads_end)
214
221
{
215
222
if (padMode == " VALID" )
216
223
{
217
- padT = padL = padB = padR = 0 ;
224
+ pads_begin.assign (kernel.size (), 0 );
225
+ pads_end.assign (kernel.size (), 0 );
218
226
}
219
227
else if (padMode == " SAME" )
220
228
{
221
- int Ph = std::max (0 , (out.height - 1 ) * stride.height + (dilation.height * (kernel.height - 1 ) + 1 ) - inp.height );
222
- int Pw = std::max (0 , (out.width - 1 ) * stride.width + (dilation.width * (kernel.width - 1 ) + 1 ) - inp.width );
223
- // For odd values of total padding, add more padding at the 'right'
224
- // side of the given dimension.
225
- padT= padB = Ph / 2 ;
226
- padL = padR = Pw / 2 ;
229
+ CV_Assert_N (kernel.size () == dilation.size (), kernel.size () == strides.size (),
230
+ kernel.size () == inp.size (), kernel.size () == out.size ());
231
+ pads_begin.resize (kernel.size ());
232
+ pads_end.resize (kernel.size ());
233
+ for (int i = 0 ; i < pads_begin.size (); i++) {
234
+ int pad = ((out[i] - 1 ) * strides[i] + dilation[i] * (kernel[i] - 1 ) + 1 - inp[i]) / 2 ;
235
+ pads_begin[i] = pads_end[i] = std::max (0 , pad);
236
+ }
227
237
}
228
238
}
229
239
0 commit comments