1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge pull request #13879 from chacha21:REDUCE_SUM2

add REDUCE_SUM2 #13879 

proposal to add REDUCE_SUM2 to cv::reduce, an operation that sums up the square of elements
This commit is contained in:
Pierre Chatelier
2023-04-28 19:42:52 +02:00
committed by GitHub
parent 23b819efb8
commit 6dd8a9b6ad
9 changed files with 254 additions and 92 deletions
+29 -15
View File
@@ -26,7 +26,7 @@ protected:
};
template<class Type>
void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim )
void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, Mat& sum2, int dim )
{
CV_Assert( src.channels() == 1 );
if( dim == 0 ) // row
@@ -34,21 +34,25 @@ void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim
sum.create( 1, src.cols, CV_64FC1 );
max.create( 1, src.cols, CV_64FC1 );
min.create( 1, src.cols, CV_64FC1 );
sum2.create( 1, src.cols, CV_64FC1 );
}
else
{
sum.create( src.rows, 1, CV_64FC1 );
max.create( src.rows, 1, CV_64FC1 );
min.create( src.rows, 1, CV_64FC1 );
sum2.create( src.rows, 1, CV_64FC1 );
}
sum.setTo(Scalar(0));
max.setTo(Scalar(-DBL_MAX));
min.setTo(Scalar(DBL_MAX));
sum2.setTo(Scalar(0));
const Mat_<Type>& src_ = src;
Mat_<double>& sum_ = (Mat_<double>&)sum;
Mat_<double>& min_ = (Mat_<double>&)min;
Mat_<double>& max_ = (Mat_<double>&)max;
Mat_<double>& sum2_ = (Mat_<double>&)sum2;
if( dim == 0 )
{
@@ -59,6 +63,7 @@ void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim
sum_(0, ci) += src_(ri, ci);
max_(0, ci) = std::max( max_(0, ci), (double)src_(ri, ci) );
min_(0, ci) = std::min( min_(0, ci), (double)src_(ri, ci) );
sum2_(0, ci) += ((double)src_(ri, ci))*((double)src_(ri, ci));
}
}
}
@@ -71,6 +76,7 @@ void testReduce( const Mat& src, Mat& sum, Mat& avg, Mat& max, Mat& min, int dim
sum_(ri, 0) += src_(ri, ci);
max_(ri, 0) = std::max( max_(ri, 0), (double)src_(ri, ci) );
min_(ri, 0) = std::min( min_(ri, 0), (double)src_(ri, ci) );
sum2_(ri, 0) += ((double)src_(ri, ci))*((double)src_(ri, ci));
}
}
}
@@ -93,7 +99,7 @@ int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat
{
int srcType = src.type();
bool support = false;
if( opType == REDUCE_SUM || opType == REDUCE_AVG )
if( opType == REDUCE_SUM || opType == REDUCE_AVG || opType == REDUCE_SUM2 )
{
if( srcType == CV_8U && (dstType == CV_32S || dstType == CV_32F || dstType == CV_64F) )
support = true;
@@ -128,7 +134,7 @@ int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat
return cvtest::TS::OK;
double eps = 0.0;
if ( opType == REDUCE_SUM || opType == REDUCE_AVG )
if ( opType == REDUCE_SUM || opType == REDUCE_AVG || opType == REDUCE_SUM2 )
{
if ( dstType == CV_32F )
eps = 1.e-5;
@@ -152,10 +158,13 @@ int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat
if( check )
{
char msg[100];
const char* opTypeStr = opType == REDUCE_SUM ? "REDUCE_SUM" :
opType == REDUCE_AVG ? "REDUCE_AVG" :
opType == REDUCE_MAX ? "REDUCE_MAX" :
opType == REDUCE_MIN ? "REDUCE_MIN" : "unknown operation type";
const char* opTypeStr =
opType == REDUCE_SUM ? "REDUCE_SUM" :
opType == REDUCE_AVG ? "REDUCE_AVG" :
opType == REDUCE_MAX ? "REDUCE_MAX" :
opType == REDUCE_MIN ? "REDUCE_MIN" :
opType == REDUCE_SUM2 ? "REDUCE_SUM2" :
"unknown operation type";
string srcTypeStr, dstTypeStr;
getMatTypeStr( src.type(), srcTypeStr );
getMatTypeStr( dstType, dstTypeStr );
@@ -172,25 +181,25 @@ int Core_ReduceTest::checkOp( const Mat& src, int dstType, int opType, const Mat
int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
{
int code = cvtest::TS::OK, tempCode;
Mat src, sum, avg, max, min;
Mat src, sum, avg, max, min, sum2;
src.create( sz, srcType );
randu( src, Scalar(0), Scalar(100) );
if( srcType == CV_8UC1 )
testReduce<uchar>( src, sum, avg, max, min, dim );
testReduce<uchar>( src, sum, avg, max, min, sum2, dim );
else if( srcType == CV_8SC1 )
testReduce<char>( src, sum, avg, max, min, dim );
testReduce<char>( src, sum, avg, max, min, sum2, dim );
else if( srcType == CV_16UC1 )
testReduce<unsigned short int>( src, sum, avg, max, min, dim );
testReduce<unsigned short int>( src, sum, avg, max, min, sum2, dim );
else if( srcType == CV_16SC1 )
testReduce<short int>( src, sum, avg, max, min, dim );
testReduce<short int>( src, sum, avg, max, min, sum2, dim );
else if( srcType == CV_32SC1 )
testReduce<int>( src, sum, avg, max, min, dim );
testReduce<int>( src, sum, avg, max, min, sum2, dim );
else if( srcType == CV_32FC1 )
testReduce<float>( src, sum, avg, max, min, dim );
testReduce<float>( src, sum, avg, max, min, sum2, dim );
else if( srcType == CV_64FC1 )
testReduce<double>( src, sum, avg, max, min, dim );
testReduce<double>( src, sum, avg, max, min, sum2, dim );
else
CV_Assert( 0 );
@@ -210,6 +219,10 @@ int Core_ReduceTest::checkCase( int srcType, int dstType, int dim, Size sz )
tempCode = checkOp( src, dstType, REDUCE_MIN, min, dim );
code = tempCode != cvtest::TS::OK ? tempCode : code;
// 5. sum2
tempCode = checkOp( src, dstType, REDUCE_SUM2, sum2, dim );
code = tempCode != cvtest::TS::OK ? tempCode : code;
return code;
}
@@ -1563,6 +1576,7 @@ TEST(Reduce, regression_should_fail_bug_4594)
EXPECT_THROW(cv::reduce(src, dst, 0, REDUCE_MAX, CV_32S), cv::Exception);
EXPECT_NO_THROW(cv::reduce(src, dst, 0, REDUCE_SUM, CV_32S));
EXPECT_NO_THROW(cv::reduce(src, dst, 0, REDUCE_AVG, CV_32S));
EXPECT_NO_THROW(cv::reduce(src, dst, 0, REDUCE_SUM2, CV_32S));
}
TEST(Mat, push_back_vector)