@@ -269,6 +269,204 @@ thresh_8u( const Mat& _src, Mat& _dst, uchar thresh, uchar maxval, int type )
269
269
}
270
270
}
271
271
272
+ static void
273
+ thresh_16u (const Mat& _src, Mat& _dst, ushort thresh, ushort maxval, int type)
274
+ {
275
+ Size roi = _src.size ();
276
+ roi.width *= _src.channels ();
277
+ size_t src_step = _src.step ;
278
+ size_t dst_step = _dst.step ;
279
+
280
+ if (_src.isContinuous () && _dst.isContinuous ())
281
+ {
282
+ roi.width *= roi.height ;
283
+ roi.height = 1 ;
284
+ src_step = dst_step = roi.width ;
285
+ }
286
+
287
+ // HAVE_TEGRA_OPTIMIZATION not supported
288
+
289
+ // HAVE_IPP not supported
290
+
291
+ int j = 0 ;
292
+ const ushort* src = _src.ptr <ushort>();
293
+ ushort* dst = _dst.ptr <ushort>();
294
+
295
+ // CV_SIMD128 not supported
296
+ #if CV_SIMD128
297
+ bool useSIMD = checkHardwareSupport (CV_CPU_SSE2) || checkHardwareSupport (CV_CPU_NEON);
298
+ if (useSIMD)
299
+ {
300
+ int i;
301
+ v_uint16x8 thresh_u = v_setall_u16 (thresh);
302
+ v_uint16x8 maxval16 = v_setall_u16 (maxval);
303
+
304
+ switch (type)
305
+ {
306
+ case THRESH_BINARY:
307
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
308
+ {
309
+ for (j = 0 ; j <= roi.width - 16 ; j += 16 )
310
+ {
311
+ v_uint16x8 v0, v1;
312
+ v0 = v_load (src + j);
313
+ v1 = v_load (src + j + 8 );
314
+ v0 = thresh_u < v0;
315
+ v1 = thresh_u < v1;
316
+ v0 = v0 & maxval16;
317
+ v1 = v1 & maxval16;
318
+ v_store (dst + j, v0);
319
+ v_store (dst + j + 8 , v1);
320
+ }
321
+ }
322
+ break ;
323
+
324
+ case THRESH_BINARY_INV:
325
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
326
+ {
327
+ j = 0 ;
328
+ for (; j <= roi.width - 16 ; j += 16 )
329
+ {
330
+ v_uint16x8 v0, v1;
331
+ v0 = v_load (src + j);
332
+ v1 = v_load (src + j + 8 );
333
+ v0 = v0 <= thresh_u;
334
+ v1 = v1 <= thresh_u;
335
+ v0 = v0 & maxval16;
336
+ v1 = v1 & maxval16;
337
+ v_store (dst + j, v0);
338
+ v_store (dst + j + 8 , v1);
339
+ }
340
+
341
+ for (; j < roi.width ; j++)
342
+ dst[j] = src[j] <= thresh ? maxval : 0 ;
343
+ }
344
+ break ;
345
+
346
+ case THRESH_TRUNC:
347
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
348
+ {
349
+ j = 0 ;
350
+ for (; j <= roi.width - 16 ; j += 16 )
351
+ {
352
+ v_uint16x8 v0, v1;
353
+ v0 = v_load (src + j);
354
+ v1 = v_load (src + j + 8 );
355
+ v0 = v_min (v0, thresh_u);
356
+ v1 = v_min (v1, thresh_u);
357
+ v_store (dst + j, v0);
358
+ v_store (dst + j + 8 , v1);
359
+ }
360
+
361
+ for (; j < roi.width ; j++)
362
+ dst[j] = std::min (src[j], thresh);
363
+ }
364
+ break ;
365
+
366
+ case THRESH_TOZERO:
367
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
368
+ {
369
+ j = 0 ;
370
+ for (; j <= roi.width - 16 ; j += 16 )
371
+ {
372
+ v_uint16x8 v0, v1;
373
+ v0 = v_load (src + j);
374
+ v1 = v_load (src + j + 8 );
375
+ v0 = (thresh_u < v0) & v0;
376
+ v1 = (thresh_u < v1) & v1;
377
+ v_store (dst + j, v0);
378
+ v_store (dst + j + 8 , v1);
379
+ }
380
+
381
+ for (; j < roi.width ; j++)
382
+ {
383
+ short v = src[j];
384
+ dst[j] = v > thresh ? v : 0 ;
385
+ }
386
+ }
387
+ break ;
388
+
389
+ case THRESH_TOZERO_INV:
390
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
391
+ {
392
+ j = 0 ;
393
+ for (; j <= roi.width - 16 ; j += 16 )
394
+ {
395
+ v_uint16x8 v0, v1;
396
+ v0 = v_load (src + j);
397
+ v1 = v_load (src + j + 8 );
398
+ v0 = (v0 <= thresh_u) & v0;
399
+ v1 = (v1 <= thresh_u) & v1;
400
+ v_store (dst + j, v0);
401
+ v_store (dst + j + 8 , v1);
402
+ }
403
+
404
+ for (; j < roi.width ; j++)
405
+ {
406
+ short v = src[j];
407
+ dst[j] = v <= thresh ? v : 0 ;
408
+ }
409
+ }
410
+ break ;
411
+ }
412
+ }
413
+ else
414
+ #endif
415
+ {
416
+ int i;
417
+ switch (type)
418
+ {
419
+ case THRESH_BINARY:
420
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
421
+ {
422
+ for (j = 0 ; j < roi.width ; j++)
423
+ dst[j] = src[j] > thresh ? maxval : 0 ;
424
+ }
425
+ break ;
426
+
427
+ case THRESH_BINARY_INV:
428
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
429
+ {
430
+ for (j = 0 ; j < roi.width ; j++)
431
+ dst[j] = src[j] <= thresh ? maxval : 0 ;
432
+ }
433
+ break ;
434
+
435
+ case THRESH_TRUNC:
436
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
437
+ {
438
+ for (j = 0 ; j < roi.width ; j++)
439
+ dst[j] = std::min (src[j], thresh);
440
+ }
441
+ break ;
442
+
443
+ case THRESH_TOZERO:
444
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
445
+ {
446
+ for (j = 0 ; j < roi.width ; j++)
447
+ {
448
+ short v = src[j];
449
+ dst[j] = v > thresh ? v : 0 ;
450
+ }
451
+ }
452
+ break ;
453
+
454
+ case THRESH_TOZERO_INV:
455
+ for (i = 0 ; i < roi.height ; i++, src += src_step, dst += dst_step)
456
+ {
457
+ for (j = 0 ; j < roi.width ; j++)
458
+ {
459
+ short v = src[j];
460
+ dst[j] = v <= thresh ? v : 0 ;
461
+ }
462
+ }
463
+ break ;
464
+ default :
465
+ CV_Error ( CV_StsBadArg, " " ); return ;
466
+ }
467
+ }
468
+ }
469
+
272
470
273
471
static void
274
472
thresh_16s ( const Mat& _src, Mat& _dst, short thresh, short maxval, int type )
@@ -1178,6 +1376,10 @@ class ThresholdRunner : public ParallelLoopBody
1178
1376
else if ( srcStripe.depth () == CV_16S )
1179
1377
{
1180
1378
thresh_16s ( srcStripe, dstStripe, (short )thresh, (short )maxval, thresholdType );
1379
+ }
1380
+ else if ( srcStripe.depth () == CV_16U )
1381
+ {
1382
+ thresh_16u ( srcStripe, dstStripe, (ushort)thresh, (ushort)maxval, thresholdType );
1181
1383
}
1182
1384
else if ( srcStripe.depth () == CV_32F )
1183
1385
{
@@ -1422,6 +1624,34 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
1422
1624
thresh = ithresh;
1423
1625
maxval = imaxval;
1424
1626
}
1627
+ else if (src.depth () == CV_16U )
1628
+ {
1629
+ int ithresh = cvFloor (thresh);
1630
+ thresh = ithresh;
1631
+ int imaxval = cvRound (maxval);
1632
+ if (type == THRESH_TRUNC)
1633
+ imaxval = ithresh;
1634
+ imaxval = saturate_cast<short >(imaxval);
1635
+
1636
+ int ushrt_min = 0 ;
1637
+ if (ithresh < ushrt_min || ithresh >= USHRT_MAX)
1638
+ {
1639
+ if (type == THRESH_BINARY || type == THRESH_BINARY_INV ||
1640
+ ((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < ushrt_min) ||
1641
+ (type == THRESH_TOZERO && ithresh >= USHRT_MAX))
1642
+ {
1643
+ int v = type == THRESH_BINARY ? (ithresh >= USHRT_MAX ? 0 : imaxval) :
1644
+ type == THRESH_BINARY_INV ? (ithresh >= USHRT_MAX ? imaxval : 0 ) :
1645
+ /* type == THRESH_TRUNC ? imaxval :*/ 0 ;
1646
+ dst.setTo (v);
1647
+ }
1648
+ else
1649
+ src.copyTo (dst);
1650
+ return thresh;
1651
+ }
1652
+ thresh = ithresh;
1653
+ maxval = imaxval;
1654
+ }
1425
1655
else if ( src.depth () == CV_32F )
1426
1656
;
1427
1657
else if ( src.depth () == CV_64F )
0 commit comments