Skip to content

Commit ca245e9

Browse files
Arvid Piehl Lauritsen Böttigerdkurt
authored andcommitted
Added support for thresholding CV_16U images.
1 parent 0624411 commit ca245e9

File tree

1 file changed

+230
-0
lines changed

1 file changed

+230
-0
lines changed

modules/imgproc/src/thresh.cpp

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,204 @@ thresh_8u( const Mat& _src, Mat& _dst, uchar thresh, uchar maxval, int type )
269269
}
270270
}
271271

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+
272470

273471
static void
274472
thresh_16s( const Mat& _src, Mat& _dst, short thresh, short maxval, int type )
@@ -1178,6 +1376,10 @@ class ThresholdRunner : public ParallelLoopBody
11781376
else if( srcStripe.depth() == CV_16S )
11791377
{
11801378
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 );
11811383
}
11821384
else if( srcStripe.depth() == CV_32F )
11831385
{
@@ -1422,6 +1624,34 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
14221624
thresh = ithresh;
14231625
maxval = imaxval;
14241626
}
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+
}
14251655
else if( src.depth() == CV_32F )
14261656
;
14271657
else if( src.depth() == CV_64F )

0 commit comments

Comments
 (0)