mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge pull request #26256 from vpisarev:expanded_tests_for_norm
extended Norm tests to prove that cv::norm() already supports all the types. cv::norm() already provides enough functionality; just extended tests to prove it. See #24887 - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
+124
-12
@@ -281,6 +281,61 @@ normL2_(const T* src, const uchar* mask, ST* _result, int len, int cn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normInf_Bool(const uchar* src, const uchar* mask, int* _result, int len, int cn)
|
||||
{
|
||||
int result = *_result;
|
||||
if( !mask )
|
||||
{
|
||||
for ( int i = 0; i < len*cn; i++ ) {
|
||||
result = std::max(result, (int)(src[i] != 0));
|
||||
if (result != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < len; i++, src += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
for( int k = 0; k < cn; k++ )
|
||||
result = std::max(result, (int)(src[k] != 0));
|
||||
if (result != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
*_result = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normL1_Bool(const uchar* src, const uchar* mask, int* _result, int len, int cn)
|
||||
{
|
||||
int result = *_result;
|
||||
if( !mask )
|
||||
{
|
||||
for ( int i = 0; i < len*cn; i++ )
|
||||
result += (int)(src[i] != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < len; i++, src += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
for( int k = 0; k < cn; k++ )
|
||||
result += (int)(src[k] != 0);
|
||||
}
|
||||
}
|
||||
*_result = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normL2_Bool(const uchar* src, const uchar* mask, int* _result, int len, int cn)
|
||||
{
|
||||
return normL1_Bool(src, mask, _result, len, cn);
|
||||
}
|
||||
|
||||
template<typename T, typename ST> int
|
||||
normDiffInf_(const T* src1, const T* src2, const uchar* mask, ST* _result, int len, int cn)
|
||||
{
|
||||
@@ -347,6 +402,61 @@ normDiffL2_(const T* src1, const T* src2, const uchar* mask, ST* _result, int le
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normDiffInf_Bool(const uchar* src1, const uchar* src2, const uchar* mask, int* _result, int len, int cn)
|
||||
{
|
||||
int result = *_result;
|
||||
if( !mask )
|
||||
{
|
||||
for( int i = 0; i < len*cn; i++ ) {
|
||||
result = std::max(result, (int)((src1[i] != 0) != (src2[i] != 0)));
|
||||
if (result != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < len; i++, src1 += cn, src2 += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
for( int k = 0; k < cn; k++ )
|
||||
result = std::max(result, (int)((src1[k] != 0) != (src2[k] != 0)));
|
||||
if (result != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
*_result = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normDiffL1_Bool(const uchar* src1, const uchar* src2, const uchar* mask, int* _result, int len, int cn)
|
||||
{
|
||||
int result = *_result;
|
||||
if( !mask )
|
||||
{
|
||||
for( int i = 0; i < len*cn; i++ )
|
||||
result += (int)((src1[i] != 0) != (src2[i] != 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < len; i++, src1 += cn, src2 += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
for( int k = 0; k < cn; k++ )
|
||||
result += (int)((src1[k] != 0) != (src2[k] != 0));
|
||||
}
|
||||
}
|
||||
*_result = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
normDiffL2_Bool(const uchar* src1, const uchar* src2, const uchar* mask, int* _result, int len, int cn)
|
||||
{
|
||||
return normDiffL1_Bool(src1, src2, mask, _result, len, cn);
|
||||
}
|
||||
|
||||
#define CV_DEF_NORM_FUNC(L, suffix, type, ntype) \
|
||||
static int norm##L##_##suffix(const type* src, const uchar* mask, ntype* r, int len, int cn) \
|
||||
{ return norm##L##_<type, ntype>(src, mask, r, len, cn); } \
|
||||
@@ -389,7 +499,7 @@ static NormFunc getNormFunc(int normType, int depth)
|
||||
(NormFunc)normInf_64f,
|
||||
(NormFunc)GET_OPTIMIZED(normInf_16f),
|
||||
(NormFunc)GET_OPTIMIZED(normInf_16bf),
|
||||
0,
|
||||
(NormFunc)normInf_Bool,
|
||||
(NormFunc)GET_OPTIMIZED(normInf_64u),
|
||||
(NormFunc)GET_OPTIMIZED(normInf_64s),
|
||||
(NormFunc)GET_OPTIMIZED(normInf_32u),
|
||||
@@ -405,7 +515,7 @@ static NormFunc getNormFunc(int normType, int depth)
|
||||
(NormFunc)normL1_64f,
|
||||
(NormFunc)GET_OPTIMIZED(normL1_16f),
|
||||
(NormFunc)GET_OPTIMIZED(normL1_16bf),
|
||||
0,
|
||||
(NormFunc)normL1_Bool,
|
||||
(NormFunc)GET_OPTIMIZED(normL1_64u),
|
||||
(NormFunc)GET_OPTIMIZED(normL1_64s),
|
||||
(NormFunc)GET_OPTIMIZED(normL1_32u),
|
||||
@@ -421,7 +531,7 @@ static NormFunc getNormFunc(int normType, int depth)
|
||||
(NormFunc)normL2_64f,
|
||||
(NormFunc)GET_OPTIMIZED(normL2_16f),
|
||||
(NormFunc)GET_OPTIMIZED(normL2_16bf),
|
||||
0,
|
||||
(NormFunc)normL2_Bool,
|
||||
(NormFunc)GET_OPTIMIZED(normL2_64u),
|
||||
(NormFunc)GET_OPTIMIZED(normL2_64s),
|
||||
(NormFunc)GET_OPTIMIZED(normL2_32u),
|
||||
@@ -446,7 +556,7 @@ static NormDiffFunc getNormDiffFunc(int normType, int depth)
|
||||
(NormDiffFunc)normDiffInf_64f,
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffInf_16f),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffInf_16bf),
|
||||
0,
|
||||
(NormDiffFunc)normDiffInf_Bool,
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffInf_64u),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffInf_64s),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffInf_32u),
|
||||
@@ -462,7 +572,7 @@ static NormDiffFunc getNormDiffFunc(int normType, int depth)
|
||||
(NormDiffFunc)normDiffL1_64f,
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL1_16f),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL1_16bf),
|
||||
0,
|
||||
(NormDiffFunc)normDiffL1_Bool,
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL1_64u),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL1_64s),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL1_32u),
|
||||
@@ -478,7 +588,7 @@ static NormDiffFunc getNormDiffFunc(int normType, int depth)
|
||||
(NormDiffFunc)normDiffL2_64f,
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL2_16f),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL2_16bf),
|
||||
0,
|
||||
(NormDiffFunc)normDiffL2_Bool,
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL2_64u),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL2_64s),
|
||||
(NormDiffFunc)GET_OPTIMIZED(normDiffL2_32u),
|
||||
@@ -788,13 +898,14 @@ double norm( InputArray _src, int normType, InputArray _mask )
|
||||
CV_CheckLT((size_t)it.size, (size_t)INT_MAX, "");
|
||||
bool is_fp16 = depth == CV_16F || depth == CV_16BF;
|
||||
|
||||
if ((normType == NORM_L1 && (depth <= CV_16S || is_fp16)) ||
|
||||
((normType == NORM_L2 || normType == NORM_L2SQR) && (depth <= CV_8S || is_fp16)))
|
||||
if ((normType == NORM_L1 && (depth <= CV_16S || depth == CV_Bool || is_fp16)) ||
|
||||
((normType == NORM_L2 || normType == NORM_L2SQR) && (depth <= CV_8S || depth == CV_Bool || is_fp16)))
|
||||
{
|
||||
// special case to handle "integer" overflow in accumulator
|
||||
const size_t esz = src.elemSize();
|
||||
const int total = (int)it.size;
|
||||
const int blockSize0 = (is_fp16 ? (1 << 10) :
|
||||
depth == CV_Bool ? (1 << 30) :
|
||||
normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn;
|
||||
const int blockSize = std::min(total, blockSize0);
|
||||
union {
|
||||
@@ -834,7 +945,7 @@ double norm( InputArray _src, int normType, InputArray _mask )
|
||||
|
||||
if( normType == NORM_INF )
|
||||
{
|
||||
if(depth <= CV_32S || depth == CV_32U)
|
||||
if(depth <= CV_32S || depth == CV_32U || depth == CV_Bool)
|
||||
return result.u;
|
||||
if (depth == CV_32F || is_fp16)
|
||||
return result.f;
|
||||
@@ -1243,13 +1354,14 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
||||
|
||||
bool is_fp16 = depth == CV_16F || depth == CV_16BF;
|
||||
|
||||
if ((normType == NORM_L1 && (depth <= CV_16S || is_fp16)) ||
|
||||
((normType == NORM_L2 || normType == NORM_L2SQR) && (depth <= CV_8S || is_fp16)))
|
||||
if ((normType == NORM_L1 && (depth <= CV_16S || depth == CV_Bool || is_fp16)) ||
|
||||
((normType == NORM_L2 || normType == NORM_L2SQR) && (depth <= CV_8S || depth == CV_Bool || is_fp16)))
|
||||
{
|
||||
// special case to handle "integer" overflow in accumulator
|
||||
const size_t esz = src1.elemSize();
|
||||
const int total = (int)it.size;
|
||||
const int blockSize0 = (is_fp16 ? (1 << 10) :
|
||||
depth == CV_Bool ? (1 << 30) :
|
||||
normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn;
|
||||
const int blockSize = std::min(total, blockSize0);
|
||||
union {
|
||||
@@ -1290,7 +1402,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
||||
|
||||
if( normType == NORM_INF )
|
||||
{
|
||||
if (depth <= CV_32S || depth == CV_32U)
|
||||
if (depth <= CV_32S || depth == CV_32U || depth == CV_Bool)
|
||||
return result.u;
|
||||
if (depth == CV_32F || is_fp16)
|
||||
return result.f;
|
||||
|
||||
Reference in New Issue
Block a user