Added support for thresholding CV_16U images.
This commit is contained in:
parent
0624411875
commit
ca245e995a
@ -269,6 +269,204 @@ thresh_8u( const Mat& _src, Mat& _dst, uchar thresh, uchar maxval, int type )
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
thresh_16u(const Mat& _src, Mat& _dst, ushort thresh, ushort maxval, int type)
|
||||
{
|
||||
Size roi = _src.size();
|
||||
roi.width *= _src.channels();
|
||||
size_t src_step = _src.step;
|
||||
size_t dst_step = _dst.step;
|
||||
|
||||
if (_src.isContinuous() && _dst.isContinuous())
|
||||
{
|
||||
roi.width *= roi.height;
|
||||
roi.height = 1;
|
||||
src_step = dst_step = roi.width;
|
||||
}
|
||||
|
||||
// HAVE_TEGRA_OPTIMIZATION not supported
|
||||
|
||||
// HAVE_IPP not supported
|
||||
|
||||
int j = 0;
|
||||
const ushort* src = _src.ptr<ushort>();
|
||||
ushort* dst = _dst.ptr<ushort>();
|
||||
|
||||
// CV_SIMD128 not supported
|
||||
#if CV_SIMD128
|
||||
bool useSIMD = checkHardwareSupport(CV_CPU_SSE2) || checkHardwareSupport(CV_CPU_NEON);
|
||||
if (useSIMD)
|
||||
{
|
||||
int i;
|
||||
v_uint16x8 thresh_u = v_setall_u16(thresh);
|
||||
v_uint16x8 maxval16 = v_setall_u16(maxval);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case THRESH_BINARY:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
for (j = 0; j <= roi.width - 16; j += 16)
|
||||
{
|
||||
v_uint16x8 v0, v1;
|
||||
v0 = v_load(src + j);
|
||||
v1 = v_load(src + j + 8);
|
||||
v0 = thresh_u < v0;
|
||||
v1 = thresh_u < v1;
|
||||
v0 = v0 & maxval16;
|
||||
v1 = v1 & maxval16;
|
||||
v_store(dst + j, v0);
|
||||
v_store(dst + j + 8, v1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_BINARY_INV:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
j = 0;
|
||||
for (; j <= roi.width - 16; j += 16)
|
||||
{
|
||||
v_uint16x8 v0, v1;
|
||||
v0 = v_load(src + j);
|
||||
v1 = v_load(src + j + 8);
|
||||
v0 = v0 <= thresh_u;
|
||||
v1 = v1 <= thresh_u;
|
||||
v0 = v0 & maxval16;
|
||||
v1 = v1 & maxval16;
|
||||
v_store(dst + j, v0);
|
||||
v_store(dst + j + 8, v1);
|
||||
}
|
||||
|
||||
for (; j < roi.width; j++)
|
||||
dst[j] = src[j] <= thresh ? maxval : 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_TRUNC:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
j = 0;
|
||||
for (; j <= roi.width - 16; j += 16)
|
||||
{
|
||||
v_uint16x8 v0, v1;
|
||||
v0 = v_load(src + j);
|
||||
v1 = v_load(src + j + 8);
|
||||
v0 = v_min(v0, thresh_u);
|
||||
v1 = v_min(v1, thresh_u);
|
||||
v_store(dst + j, v0);
|
||||
v_store(dst + j + 8, v1);
|
||||
}
|
||||
|
||||
for (; j < roi.width; j++)
|
||||
dst[j] = std::min(src[j], thresh);
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_TOZERO:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
j = 0;
|
||||
for (; j <= roi.width - 16; j += 16)
|
||||
{
|
||||
v_uint16x8 v0, v1;
|
||||
v0 = v_load(src + j);
|
||||
v1 = v_load(src + j + 8);
|
||||
v0 = (thresh_u < v0) & v0;
|
||||
v1 = (thresh_u < v1) & v1;
|
||||
v_store(dst + j, v0);
|
||||
v_store(dst + j + 8, v1);
|
||||
}
|
||||
|
||||
for (; j < roi.width; j++)
|
||||
{
|
||||
short v = src[j];
|
||||
dst[j] = v > thresh ? v : 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_TOZERO_INV:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
j = 0;
|
||||
for (; j <= roi.width - 16; j += 16)
|
||||
{
|
||||
v_uint16x8 v0, v1;
|
||||
v0 = v_load(src + j);
|
||||
v1 = v_load(src + j + 8);
|
||||
v0 = (v0 <= thresh_u) & v0;
|
||||
v1 = (v1 <= thresh_u) & v1;
|
||||
v_store(dst + j, v0);
|
||||
v_store(dst + j + 8, v1);
|
||||
}
|
||||
|
||||
for (; j < roi.width; j++)
|
||||
{
|
||||
short v = src[j];
|
||||
dst[j] = v <= thresh ? v : 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
switch (type)
|
||||
{
|
||||
case THRESH_BINARY:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
for (j = 0; j < roi.width; j++)
|
||||
dst[j] = src[j] > thresh ? maxval : 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_BINARY_INV:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
for (j = 0; j < roi.width; j++)
|
||||
dst[j] = src[j] <= thresh ? maxval : 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_TRUNC:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
for (j = 0; j < roi.width; j++)
|
||||
dst[j] = std::min(src[j], thresh);
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_TOZERO:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
for (j = 0; j < roi.width; j++)
|
||||
{
|
||||
short v = src[j];
|
||||
dst[j] = v > thresh ? v : 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case THRESH_TOZERO_INV:
|
||||
for (i = 0; i < roi.height; i++, src += src_step, dst += dst_step)
|
||||
{
|
||||
for (j = 0; j < roi.width; j++)
|
||||
{
|
||||
short v = src[j];
|
||||
dst[j] = v <= thresh ? v : 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CV_Error( CV_StsBadArg, "" ); return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
thresh_16s( const Mat& _src, Mat& _dst, short thresh, short maxval, int type )
|
||||
@ -1178,6 +1376,10 @@ public:
|
||||
else if( srcStripe.depth() == CV_16S )
|
||||
{
|
||||
thresh_16s( srcStripe, dstStripe, (short)thresh, (short)maxval, thresholdType );
|
||||
}
|
||||
else if( srcStripe.depth() == CV_16U )
|
||||
{
|
||||
thresh_16u( srcStripe, dstStripe, (ushort)thresh, (ushort)maxval, thresholdType );
|
||||
}
|
||||
else if( srcStripe.depth() == CV_32F )
|
||||
{
|
||||
@ -1422,6 +1624,34 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
|
||||
thresh = ithresh;
|
||||
maxval = imaxval;
|
||||
}
|
||||
else if (src.depth() == CV_16U )
|
||||
{
|
||||
int ithresh = cvFloor(thresh);
|
||||
thresh = ithresh;
|
||||
int imaxval = cvRound(maxval);
|
||||
if (type == THRESH_TRUNC)
|
||||
imaxval = ithresh;
|
||||
imaxval = saturate_cast<short>(imaxval);
|
||||
|
||||
int ushrt_min = 0;
|
||||
if (ithresh < ushrt_min || ithresh >= USHRT_MAX)
|
||||
{
|
||||
if (type == THRESH_BINARY || type == THRESH_BINARY_INV ||
|
||||
((type == THRESH_TRUNC || type == THRESH_TOZERO_INV) && ithresh < ushrt_min) ||
|
||||
(type == THRESH_TOZERO && ithresh >= USHRT_MAX))
|
||||
{
|
||||
int v = type == THRESH_BINARY ? (ithresh >= USHRT_MAX ? 0 : imaxval) :
|
||||
type == THRESH_BINARY_INV ? (ithresh >= USHRT_MAX ? imaxval : 0) :
|
||||
/*type == THRESH_TRUNC ? imaxval :*/ 0;
|
||||
dst.setTo(v);
|
||||
}
|
||||
else
|
||||
src.copyTo(dst);
|
||||
return thresh;
|
||||
}
|
||||
thresh = ithresh;
|
||||
maxval = imaxval;
|
||||
}
|
||||
else if( src.depth() == CV_32F )
|
||||
;
|
||||
else if( src.depth() == CV_64F )
|
||||
|
||||
Loading…
Reference in New Issue
Block a user