@@ -226,6 +226,7 @@ static void makeMinSparseTableMat(InputArray src, OutputArray dst, int rowStep,
226
226
{
227
227
for (int colCh = 0 ; colCh < colChLim; colCh++)
228
228
{
229
+ // Somehow min(a,b) or a<b?a:b are slower.
229
230
if (*srcPtr1 < *srcPtr2)
230
231
{
231
232
*dstPtr++ = *srcPtr1++;
@@ -284,19 +285,12 @@ void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor,
284
285
void erode (InputArray _src, OutputArray _dst, InputArray _kernel, Point anchor,
285
286
int borderType, const Scalar& borderValue)
286
287
{
287
- // ---------------------------
288
- // checking input
289
288
uchar ZERO = 255 ;
290
289
291
290
Mat src = _src.getMat ();
292
- Mat dst = _dst.getMat ();
293
291
Mat kernel = _kernel.getMat ();
294
292
anchor = stMorph::normalizeAnchor (anchor, kernel.size ());
295
293
296
- // iterations; is it needed yet?
297
- // borderType; BORDER_CONSTANT
298
-
299
- dst.setTo (ZERO);
300
294
Scalar bV = borderValue;
301
295
if (borderType == cv::BorderTypes::BORDER_CONSTANT && borderValue == cv::morphologyDefaultBorderValue ())
302
296
{
@@ -305,37 +299,37 @@ void erode(InputArray _src, OutputArray _dst, InputArray _kernel, Point anchor,
305
299
// need to think CV_8U/CV_16U/CV_16S/CV_32F/CV64F
306
300
}
307
301
308
- // ---------------------------
309
- // pre processing
310
-
311
- // adding border to the source.
312
- // borderType := cv::BorderTypes::BORDER_CONSTANT(0)
313
- // borderValue := DBL_MAX => { MAX_VALUE (when erasion); MIN_VALUE (when dilation) }
314
- Mat expandedSrc (src.rows + kernel.rows , src.cols + kernel.cols , src.type ());
315
- cv::copyMakeBorder (src, expandedSrc, anchor.y , kernel.cols - 1 - anchor.y , anchor.x , kernel.rows - 1 - anchor.x , borderType, bV);
316
-
317
- // log2 table construction
318
- int len = max (kernel.rows , kernel.cols ) + 1 ;
319
- std::vector<int > log2 (len);
320
- for (int i = 2 ; i < len; i++) log2[i] = log2[i >> 1 ] + 1 ;
321
-
322
- // カーネルから幅と高さが2のべき乗の長方形リストを生成する
323
- // - リストの width と height は log2 をとった値
302
+ // Generate list of rectangles whose width and height are power of 2.
303
+ // (The width and height values of returned rects are the log2 of the actual values.)
324
304
std::vector<Rect> pow2Rects = genPow2RectsToCoverKernel (kernel);
325
305
326
- // 幅と高さが2のべき乗の長方形リストを幅と高さごとに集計
327
- std::vector<std::vector<bool >> sparseMatMap (log2[kernel.rows ] + 1 , std::vector<bool >(log2[kernel.cols ] + 1 , false ));
306
+ // get the depth limits
307
+ int rowDepthLim = 0 , colDepthLim = 0 ;
308
+ for (int i = 0 ; i < pow2Rects.size (); i++)
309
+ {
310
+ if (rowDepthLim < pow2Rects[i].height ) rowDepthLim = pow2Rects[i].height ;
311
+ if (colDepthLim < pow2Rects[i].width ) colDepthLim = pow2Rects[i].width ;
312
+ }
313
+ rowDepthLim++;
314
+ colDepthLim++;
315
+
316
+ // list up required sparse table nodes.
317
+ std::vector<std::vector<bool >> sparseMatMap (rowDepthLim, std::vector<bool >(colDepthLim, false ));
328
318
for (int i = 0 ; i < pow2Rects.size (); i++) sparseMatMap[pow2Rects[i].height ][pow2Rects[i].width ] = true ;
329
319
330
- // スパーステーブルの生成計画を立てる; planning how to calculate required mats in sparse table
331
- std::vector<StStep> stProcess = planSparseTableConstruction (sparseMatMap);
320
+ // plan how to calculate required nodes of 2D sparse table.
321
+ std::vector<StStep> stPlan = planSparseTableConstruction (sparseMatMap);
332
322
333
- // スパーステーブルの生成; generate sparse table
334
- std::vector<std::vector<Mat*>> st (log2[kernel.rows ] + 1 , std::vector<Mat*>(log2[kernel.cols ] + 1 ));
323
+ // adding border to the source.
324
+ Mat expandedSrc (src.rows + kernel.rows , src.cols + kernel.cols , src.type ());
325
+ cv::copyMakeBorder (src, expandedSrc, anchor.y , kernel.cols - 1 - anchor.y , anchor.x , kernel.rows - 1 - anchor.x , borderType, bV);
326
+
327
+ // calculate sparse table nodes
328
+ std::vector<std::vector<Mat*>> st (rowDepthLim, std::vector<Mat*>(colDepthLim));
335
329
st[0 ][0 ] = &expandedSrc;
336
- for (int i = 0 ; i < stProcess .size (); i++)
330
+ for (int i = 0 ; i < stPlan .size (); i++)
337
331
{
338
- StStep step = stProcess [i];
332
+ StStep step = stPlan [i];
339
333
switch (step.ax )
340
334
{
341
335
case Dim::Col:
@@ -349,14 +343,15 @@ void erode(InputArray _src, OutputArray _dst, InputArray _kernel, Point anchor,
349
343
}
350
344
}
351
345
352
- // 結果構築; construct the result
346
+ // result constructioin
347
+ Mat dst = _dst.getMat ();
348
+ dst.setTo (ZERO);
349
+ int colChLim = src.cols * src.channels ();
353
350
for (int i = 0 ; i < pow2Rects.size (); i++)
354
351
{
355
352
Rect rect = pow2Rects[i];
356
353
Mat sparseMat = *st[rect.height ][rect.width ];
357
354
int sideBorderSkipStep = (kernel.cols - 1 ) * sparseMat.step .p [1 ];
358
- int colChLim = src.cols * src.channels ();
359
-
360
355
uchar* srcPtr = sparseMat.ptr (rect.y , rect.x );
361
356
uchar* dstPtr = dst.ptr ();
362
357
for (int row = 0 ; row < src.rows ; row++)
0 commit comments