diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 5b5b724f0..3d3b23e13 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -1270,7 +1270,7 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) int depth = src.depth(), cn = src.channels(); normType &= 7; - CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR || ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src.type() == CV_8U) ); if( src.isContinuous() && mask.empty() ) @@ -1288,6 +1288,12 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1); return std::sqrt(result); } + if( normType == NORM_L2SQR ) + { + double result = 0; + GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1); + return result; + } if( normType == NORM_L1 ) { double result = 0; @@ -1354,7 +1360,7 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) NAryMatIterator it(arrays, ptrs); int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0; bool blockSum = (normType == NORM_L1 && depth <= CV_16S) || - (normType == NORM_L2 && depth <= CV_8S); + ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S); int isum = 0; int *ibuf = &result.i; size_t esz = 0; @@ -1413,7 +1419,7 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m CV_Assert( src1.size == src2.size && src1.type() == src2.type() ); normType &= 7; - CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || + CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR || ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) ); if( src1.isContinuous() && src2.isContinuous() && mask.empty() ) @@ -1432,6 +1438,12 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1); return std::sqrt(result); } + if( normType == NORM_L2SQR ) + { + double result = 0; + GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1); + return result; + } if( normType == NORM_L1 ) { double result = 0; @@ -1490,7 +1502,7 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m NAryMatIterator it(arrays, ptrs); int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0; bool blockSum = (normType == NORM_L1 && depth <= CV_16S) || - (normType == NORM_L2 && depth <= CV_8S); + ((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S); unsigned isum = 0; unsigned *ibuf = &result.u; size_t esz = 0; diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index 3256cb7c1..7faa919e4 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -1227,11 +1227,17 @@ struct NormOp : public BaseElemWiseOp int getRandomType(RNG& rng) { int type = cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4); - normType = 1 << rng.uniform(0, 3); - if( CV_MAT_DEPTH(type) == CV_8U && (rng.next() & 8) != 0 ) + for(;;) { - normType = cv::NORM_HAMMING + rng.uniform(0, 2); - type = CV_MAT_DEPTH(type); + normType = rng.uniform(1, 8); + if( normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR || + normType == NORM_HAMMING || normType == NORM_HAMMING2 ) + break; + } + if( normType == NORM_HAMMING || normType == NORM_HAMMING2 ) + { + type = CV_8U; } return type; } diff --git a/modules/ts/src/ts_func.cpp b/modules/ts/src/ts_func.cpp index 103b29ea0..ee12665fe 100644 --- a/modules/ts/src/ts_func.cpp +++ b/modules/ts/src/ts_func.cpp @@ -1257,6 +1257,8 @@ double norm(const Mat& src, int normType, const Mat& mask) result += normHamming(planes[0].data, total, cellSize); return result; } + int normType0 = normType; + normType = normType == NORM_L2SQR ? NORM_L2 : normType; CV_Assert( mask.empty() || (src.size == mask.size && mask.type() == CV_8U) ); CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 ); @@ -1302,7 +1304,7 @@ double norm(const Mat& src, int normType, const Mat& mask) CV_Error(CV_StsUnsupportedFormat, ""); }; } - if( normType == NORM_L2 ) + if( normType0 == NORM_L2 ) result = sqrt(result); return result; } @@ -1332,6 +1334,8 @@ double norm(const Mat& src1, const Mat& src2, int normType, const Mat& mask) result += normHamming(planes[0].data, total, cellSize); return result; } + int normType0 = normType; + normType = normType == NORM_L2SQR ? NORM_L2 : normType; CV_Assert( src1.type() == src2.type() && src1.size == src2.size ); CV_Assert( mask.empty() || (src1.size == mask.size && mask.type() == CV_8U) ); @@ -1378,7 +1382,7 @@ double norm(const Mat& src1, const Mat& src2, int normType, const Mat& mask) CV_Error(CV_StsUnsupportedFormat, ""); }; } - if( normType == NORM_L2 ) + if( normType0 == NORM_L2 ) result = sqrt(result); return result; }