mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Extended several core functions to support new types (#24962)
* started adding support for new types (16f, 16bf, 32u, 64u, 64s) to arithmetic functions * fixed several tests; refactored and extended sum(), extended inRange(). * extended countNonZero(), mean(), meanStdDev(), minMaxIdx(), norm() and sum() to support new types (F16, BF16, U32, U64, S64) * put missing CV_DEPTH_MAX to some function dispatcher tables * extended findnonzero, hasnonzero with the new types support * extended mixChannels() to support new types * minor fix * fixed a few compile errors on Linux and a few failures in core tests * fixed a few more warnings and test failures * trying to fix the remaining warnings and test failures. The test `MulTestGPU.MathOpTest` was disabled - not clear whether to set tolerance - it's not bit-exact operation, as possibly assumed by the test, due to the use of scale and possibly limited accuracy of the intermediate floating-point calculations. * found that in the current snapshot G-API produces incorrect results in Mul, Div and AddWeighted (at least when using OpenCL on Windows x64 or MacOS x64). Disabled the respective tests.
This commit is contained in:
+216
-43
@@ -331,10 +331,19 @@ static BinaryFuncC* getMaxTab()
|
||||
{
|
||||
static BinaryFuncC maxTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::max8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::max16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max32s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max32f), (BinaryFuncC)cv::hal::max64f,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max32f),
|
||||
(BinaryFuncC)cv::hal::max64f,
|
||||
(BinaryFuncC)cv::hal::max16f,
|
||||
(BinaryFuncC)cv::hal::max16bf,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::max8u), // bool
|
||||
(BinaryFuncC)cv::hal::max64u,
|
||||
(BinaryFuncC)cv::hal::max64s,
|
||||
(BinaryFuncC)cv::hal::max32u,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -345,10 +354,19 @@ static BinaryFuncC* getMinTab()
|
||||
{
|
||||
static BinaryFuncC minTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::min8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::min16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min32s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min32f), (BinaryFuncC)cv::hal::min64f,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min32f),
|
||||
(BinaryFuncC)cv::hal::min64f,
|
||||
(BinaryFuncC)cv::hal::min16f,
|
||||
(BinaryFuncC)cv::hal::min16bf,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::min8u), // bool
|
||||
(BinaryFuncC)cv::hal::min64u,
|
||||
(BinaryFuncC)cv::hal::min64s,
|
||||
(BinaryFuncC)cv::hal::min32u,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -462,6 +480,14 @@ static int actualScalarDepth(const double* data, int len)
|
||||
CV_32S;
|
||||
}
|
||||
|
||||
static int coerceTypes(int depth1, int depth2, bool muldiv)
|
||||
{
|
||||
return depth1 == depth2 ? depth1 :
|
||||
((depth1 <= CV_32S) & (depth2 <= CV_32S)) != 0 ?
|
||||
(((int)!muldiv & (depth1 <= CV_8S) & (depth2 <= CV_8S)) != 0 ? CV_16S : CV_32S) :
|
||||
((CV_ELEM_SIZE1(depth1) > 4) | (CV_ELEM_SIZE1(depth2) > 4)) != 0 ? CV_64F : CV_32F;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
@@ -658,7 +684,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
{
|
||||
Mat sc = psrc2->getMat();
|
||||
depth2 = actualScalarDepth(sc.ptr<double>(), sz2 == Size(1, 1) ? cn2 : cn);
|
||||
if( depth2 == CV_64F && (depth1 < CV_32S || depth1 == CV_32F) )
|
||||
if( depth2 == CV_64F && CV_ELEM_SIZE1(depth1) < 8 )
|
||||
depth2 = CV_32F;
|
||||
}
|
||||
else
|
||||
@@ -684,9 +710,8 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
wtype = dtype;
|
||||
else if( !muldiv )
|
||||
{
|
||||
wtype = depth1 <= CV_8S && depth2 <= CV_8S ? CV_16S :
|
||||
depth1 <= CV_32S && depth2 <= CV_32S ? CV_32S : std::max(depth1, depth2);
|
||||
wtype = std::max(wtype, dtype);
|
||||
wtype = coerceTypes(depth1, depth2, false);
|
||||
wtype = coerceTypes(wtype, dtype, false);
|
||||
|
||||
// when the result of addition should be converted to an integer type,
|
||||
// and just one of the input arrays is floating-point, it makes sense to convert that input to integer type before the operation,
|
||||
@@ -696,8 +721,8 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
}
|
||||
else
|
||||
{
|
||||
wtype = std::max(depth1, std::max(depth2, CV_32F));
|
||||
wtype = std::max(wtype, dtype);
|
||||
wtype = coerceTypes(depth1, depth2, true);
|
||||
wtype = coerceTypes(wtype, dtype, true);
|
||||
}
|
||||
|
||||
dtype = CV_MAKETYPE(dtype, cn);
|
||||
@@ -873,10 +898,19 @@ static BinaryFuncC* getAddTab()
|
||||
{
|
||||
static BinaryFuncC addTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::add8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::add16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add32s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add32f), (BinaryFuncC)cv::hal::add64f,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::add32f),
|
||||
(BinaryFuncC)cv::hal::add64f,
|
||||
(BinaryFuncC)cv::hal::add16f,
|
||||
(BinaryFuncC)cv::hal::add16bf,
|
||||
0,
|
||||
(BinaryFuncC)cv::hal::add64u,
|
||||
(BinaryFuncC)cv::hal::add64s,
|
||||
(BinaryFuncC)cv::hal::add32u,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -887,10 +921,19 @@ static BinaryFuncC* getSubTab()
|
||||
{
|
||||
static BinaryFuncC subTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::sub8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::sub16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub32s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub32f), (BinaryFuncC)cv::hal::sub64f,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::sub32f),
|
||||
(BinaryFuncC)cv::hal::sub64f,
|
||||
(BinaryFuncC)cv::hal::sub16f,
|
||||
(BinaryFuncC)cv::hal::sub16bf,
|
||||
0,
|
||||
(BinaryFuncC)cv::hal::sub64u,
|
||||
(BinaryFuncC)cv::hal::sub64s,
|
||||
(BinaryFuncC)cv::hal::sub32u,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -901,10 +944,19 @@ static BinaryFuncC* getAbsDiffTab()
|
||||
{
|
||||
static BinaryFuncC absDiffTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff32s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff32f), (BinaryFuncC)cv::hal::absdiff64f,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::absdiff32f),
|
||||
(BinaryFuncC)cv::hal::absdiff64f,
|
||||
(BinaryFuncC)cv::hal::absdiff16f,
|
||||
(BinaryFuncC)cv::hal::absdiff16bf,
|
||||
0,
|
||||
(BinaryFuncC)cv::hal::absdiff64u,
|
||||
(BinaryFuncC)cv::hal::absdiff64s,
|
||||
(BinaryFuncC)cv::hal::absdiff32u,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -956,7 +1008,8 @@ static BinaryFuncC* getMulTab()
|
||||
{
|
||||
(BinaryFuncC)cv::hal::mul8u, (BinaryFuncC)cv::hal::mul8s, (BinaryFuncC)cv::hal::mul16u,
|
||||
(BinaryFuncC)cv::hal::mul16s, (BinaryFuncC)cv::hal::mul32s, (BinaryFuncC)cv::hal::mul32f,
|
||||
(BinaryFuncC)cv::hal::mul64f, 0
|
||||
(BinaryFuncC)cv::hal::mul64f, (BinaryFuncC)cv::hal::mul16f, (BinaryFuncC)cv::hal::mul16bf, 0,
|
||||
(BinaryFuncC)cv::hal::mul64u, (BinaryFuncC)cv::hal::mul64s, (BinaryFuncC)cv::hal::mul32u, 0
|
||||
};
|
||||
|
||||
return mulTab;
|
||||
@@ -968,7 +1021,8 @@ static BinaryFuncC* getDivTab()
|
||||
{
|
||||
(BinaryFuncC)cv::hal::div8u, (BinaryFuncC)cv::hal::div8s, (BinaryFuncC)cv::hal::div16u,
|
||||
(BinaryFuncC)cv::hal::div16s, (BinaryFuncC)cv::hal::div32s, (BinaryFuncC)cv::hal::div32f,
|
||||
(BinaryFuncC)cv::hal::div64f, 0
|
||||
(BinaryFuncC)cv::hal::div64f, (BinaryFuncC)cv::hal::div16f, (BinaryFuncC)cv::hal::div16bf, 0,
|
||||
(BinaryFuncC)cv::hal::div64u, (BinaryFuncC)cv::hal::div64s, (BinaryFuncC)cv::hal::div32u, 0
|
||||
};
|
||||
|
||||
return divTab;
|
||||
@@ -980,7 +1034,8 @@ static BinaryFuncC* getRecipTab()
|
||||
{
|
||||
(BinaryFuncC)cv::hal::recip8u, (BinaryFuncC)cv::hal::recip8s, (BinaryFuncC)cv::hal::recip16u,
|
||||
(BinaryFuncC)cv::hal::recip16s, (BinaryFuncC)cv::hal::recip32s, (BinaryFuncC)cv::hal::recip32f,
|
||||
(BinaryFuncC)cv::hal::recip64f, 0
|
||||
(BinaryFuncC)cv::hal::recip64f, (BinaryFuncC)cv::hal::recip16f, (BinaryFuncC)cv::hal::recip16bf, 0,
|
||||
(BinaryFuncC)cv::hal::recip64u, (BinaryFuncC)cv::hal::recip64s, (BinaryFuncC)cv::hal::recip32u, 0
|
||||
};
|
||||
|
||||
return recipTab;
|
||||
@@ -1026,9 +1081,18 @@ static BinaryFuncC* getAddWeightedTab()
|
||||
{
|
||||
static BinaryFuncC addWeightedTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted8s), (BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted16s), (BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted32s), (BinaryFuncC)cv::hal::addWeighted32f,
|
||||
(BinaryFuncC)cv::hal::addWeighted64f, 0
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::addWeighted32s),
|
||||
(BinaryFuncC)cv::hal::addWeighted32f,
|
||||
(BinaryFuncC)cv::hal::addWeighted64f,
|
||||
(BinaryFuncC)cv::hal::addWeighted16f,
|
||||
(BinaryFuncC)cv::hal::addWeighted16bf, 0,
|
||||
(BinaryFuncC)cv::hal::addWeighted64u,
|
||||
(BinaryFuncC)cv::hal::addWeighted64s,
|
||||
(BinaryFuncC)cv::hal::addWeighted32u, 0
|
||||
};
|
||||
|
||||
return addWeightedTab;
|
||||
@@ -1057,10 +1121,19 @@ static BinaryFuncC getCmpFunc(int depth)
|
||||
{
|
||||
static BinaryFuncC cmpTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp8u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp16u), (BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp8u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp8s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp16u),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp16s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp32s),
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp32f), (BinaryFuncC)cv::hal::cmp64f,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp32f),
|
||||
(BinaryFuncC)cv::hal::cmp64f,
|
||||
(BinaryFuncC)cv::hal::cmp16f,
|
||||
(BinaryFuncC)cv::hal::cmp16bf,
|
||||
0,
|
||||
(BinaryFuncC)cv::hal::cmp64u,
|
||||
(BinaryFuncC)cv::hal::cmp64s,
|
||||
(BinaryFuncC)cv::hal::cmp32u,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -1069,13 +1142,20 @@ static BinaryFuncC getCmpFunc(int depth)
|
||||
|
||||
static double getMinVal(int depth)
|
||||
{
|
||||
static const double tab[] = {0, -128, 0, -32768, INT_MIN, -FLT_MAX, -DBL_MAX, 0};
|
||||
static const double tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
0, -128, 0, -32768, INT_MIN, -FLT_MAX, -DBL_MAX,
|
||||
-65504, -FLT_MAX, 0, 0, (double)INT64_MIN, 0
|
||||
};
|
||||
return tab[depth];
|
||||
}
|
||||
|
||||
static double getMaxVal(int depth)
|
||||
{
|
||||
static const double tab[] = {255, 127, 65535, 32767, INT_MAX, FLT_MAX, DBL_MAX, 0};
|
||||
static const double tab[CV_DEPTH_MAX] = {
|
||||
255, 127, 65535, 32767, INT_MAX, FLT_MAX, DBL_MAX,
|
||||
65504, FLT_MAX, 255, (double)UINT64_MAX, (double)INT64_MAX, (double)UINT32_MAX, 0
|
||||
};
|
||||
return tab[depth];
|
||||
}
|
||||
|
||||
@@ -1220,10 +1300,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
|
||||
|
||||
_InputArray::KindFlag kind1 = _src1.kind(), kind2 = _src2.kind();
|
||||
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
|
||||
|
||||
int depth1 = src1.depth(), depth2 = src2.depth();
|
||||
if (depth1 == CV_16F || depth2 == CV_16F)
|
||||
CV_Error(Error::StsNotImplemented, "Unsupported depth value CV_16F");
|
||||
|
||||
if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 && src1.size() == src2.size() && src1.type() == src2.type() )
|
||||
{
|
||||
@@ -1270,7 +1347,8 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
|
||||
AutoBuffer<uchar> _buf(blocksize*esz);
|
||||
uchar *buf = _buf.data();
|
||||
|
||||
if( depth1 > CV_32S )
|
||||
if( ((depth1 == CV_16F) | (depth1 == CV_16BF) |
|
||||
(depth1 == CV_32F) | (depth1 == CV_64F)) != 0 )
|
||||
convertAndUnrollScalar( src2, depth1, buf, blocksize );
|
||||
else
|
||||
{
|
||||
@@ -1290,20 +1368,20 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
|
||||
return;
|
||||
}
|
||||
|
||||
int ival = cvRound(fval);
|
||||
double ival = round(fval);
|
||||
if( fval != ival )
|
||||
{
|
||||
if( op == CMP_LT || op == CMP_GE )
|
||||
ival = cvCeil(fval);
|
||||
ival = ceil(fval);
|
||||
else if( op == CMP_LE || op == CMP_GT )
|
||||
ival = cvFloor(fval);
|
||||
ival = floor(fval);
|
||||
else
|
||||
{
|
||||
dst = Scalar::all(op == CMP_NE ? 255 : 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
convertAndUnrollScalar(Mat(1, 1, CV_32S, &ival), depth1, buf, blocksize);
|
||||
convertAndUnrollScalar(Mat(1, 1, CV_64F, &ival), depth1, buf, blocksize);
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
@@ -1486,6 +1564,60 @@ struct InRange_SIMD<float>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct InRange_SIMD<float16_t>
|
||||
{
|
||||
int operator () (const float16_t * src1, const float16_t * src2, const float16_t * src3,
|
||||
uchar * dst, int len) const
|
||||
{
|
||||
int x = 0;
|
||||
const int width = (int)VTraits<v_float32>::vlanes()*2;
|
||||
|
||||
for (; x <= len - width; x += width)
|
||||
{
|
||||
v_float32 values1 = vx_load_expand(src1 + x);
|
||||
v_float32 low1 = vx_load_expand(src2 + x);
|
||||
v_float32 high1 = vx_load_expand(src3 + x);
|
||||
|
||||
v_float32 values2 = vx_load_expand(src1 + x + VTraits<v_float32>::vlanes());
|
||||
v_float32 low2 = vx_load_expand(src2 + x + VTraits<v_float32>::vlanes());
|
||||
v_float32 high2 = vx_load_expand(src3 + x + VTraits<v_float32>::vlanes());
|
||||
|
||||
v_pack_store(dst + x, v_pack(v_and(v_reinterpret_as_u32(v_ge(values1, low1)), v_reinterpret_as_u32(v_ge(high1, values1))),
|
||||
v_and(v_reinterpret_as_u32(v_ge(values2, low2)), v_reinterpret_as_u32(v_ge(high2, values2)))));
|
||||
}
|
||||
vx_cleanup();
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct InRange_SIMD<bfloat16_t>
|
||||
{
|
||||
int operator () (const bfloat16_t * src1, const bfloat16_t * src2, const bfloat16_t * src3,
|
||||
uchar * dst, int len) const
|
||||
{
|
||||
int x = 0;
|
||||
const int width = (int)VTraits<v_float32>::vlanes()*2;
|
||||
|
||||
for (; x <= len - width; x += width)
|
||||
{
|
||||
v_float32 values1 = vx_load_expand(src1 + x);
|
||||
v_float32 low1 = vx_load_expand(src2 + x);
|
||||
v_float32 high1 = vx_load_expand(src3 + x);
|
||||
|
||||
v_float32 values2 = vx_load_expand(src1 + x + VTraits<v_float32>::vlanes());
|
||||
v_float32 low2 = vx_load_expand(src2 + x + VTraits<v_float32>::vlanes());
|
||||
v_float32 high2 = vx_load_expand(src3 + x + VTraits<v_float32>::vlanes());
|
||||
|
||||
v_pack_store(dst + x, v_pack(v_and(v_reinterpret_as_u32(v_ge(values1, low1)), v_reinterpret_as_u32(v_ge(high1, values1))),
|
||||
v_and(v_reinterpret_as_u32(v_ge(values2, low2)), v_reinterpret_as_u32(v_ge(high2, values2)))));
|
||||
}
|
||||
vx_cleanup();
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
@@ -1544,12 +1676,30 @@ static void inRange16s(const short* src1, size_t step1, const short* src2, size_
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange32u(const unsigned* src1, size_t step1, const unsigned* src2, size_t step2,
|
||||
const unsigned* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange32s(const int* src1, size_t step1, const int* src2, size_t step2,
|
||||
const int* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange64u(const uint64* src1, size_t step1, const uint64* src2, size_t step2,
|
||||
const uint64* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange64s(const int64* src1, size_t step1, const int64* src2, size_t step2,
|
||||
const int64* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange32f(const float* src1, size_t step1, const float* src2, size_t step2,
|
||||
const float* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
@@ -1562,6 +1712,18 @@ static void inRange64f(const double* src1, size_t step1, const double* src2, siz
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange16f(const float16_t* src1, size_t step1, const float16_t* src2, size_t step2,
|
||||
const float16_t* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRange16bf(const bfloat16_t* src1, size_t step1, const bfloat16_t* src2, size_t step2,
|
||||
const bfloat16_t* src3, size_t step3, uchar* dst, size_t step, Size size)
|
||||
{
|
||||
inRange_(src1, step1, src2, step2, src3, step3, dst, step, size);
|
||||
}
|
||||
|
||||
static void inRangeReduce(const uchar* src, uchar* dst, size_t len, int cn)
|
||||
{
|
||||
int k = cn % 4 ? cn % 4 : 4;
|
||||
@@ -1593,9 +1755,20 @@ static InRangeFunc getInRangeFunc(int depth)
|
||||
{
|
||||
static InRangeFunc inRangeTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange8u), (InRangeFunc)GET_OPTIMIZED(inRange8s), (InRangeFunc)GET_OPTIMIZED(inRange16u),
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange16s), (InRangeFunc)GET_OPTIMIZED(inRange32s), (InRangeFunc)GET_OPTIMIZED(inRange32f),
|
||||
(InRangeFunc)inRange64f, 0
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange8u),
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange8s),
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange16u),
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange16s),
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange32s),
|
||||
(InRangeFunc)GET_OPTIMIZED(inRange32f),
|
||||
(InRangeFunc)inRange64f,
|
||||
(InRangeFunc)inRange16f,
|
||||
(InRangeFunc)inRange16bf,
|
||||
0,
|
||||
(InRangeFunc)inRange64u,
|
||||
(InRangeFunc)inRange64s,
|
||||
(InRangeFunc)inRange32u,
|
||||
0,
|
||||
};
|
||||
|
||||
return inRangeTab[depth];
|
||||
|
||||
Reference in New Issue
Block a user