Revert changes of mean and meanStdDev
This commit is contained in:
parent
46a668c565
commit
7ec59fc097
@ -608,7 +608,7 @@ CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx );
|
||||
|
||||
The function cv::mean calculates the mean value M of array elements,
|
||||
independently for each channel, and return it:
|
||||
\f[\begin{array}{l} N_c = \sum _{I: \; {\texttt{mask} (I)_c} \ne 0} 1 \\ M_c = \left ( \sum _{I: \; {\texttt{mask} (I)_c} \ne 0}{ \texttt{src} (I)_c} \right )/N_c \end{array}\f]
|
||||
\f[\begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array}\f]
|
||||
When all the mask elements are 0's, the function returns Scalar::all(0)
|
||||
@param src input array that should have from 1 to 4 channels so that the result can be stored in
|
||||
Scalar_ .
|
||||
@ -622,7 +622,7 @@ CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask = noArray());
|
||||
The function cv::meanStdDev calculates the mean and the standard deviation M
|
||||
of array elements independently for each channel and returns it via the
|
||||
output parameters:
|
||||
\f[\begin{array}{l} N_c = \sum _{I, {\texttt{mask} (I)_c} \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; {\texttt{mask} (I)_c} \ne 0} \texttt{src} (I)_c}{N_c} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; {\texttt{mask} (I)_c} \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N_c}} \end{array}\f]
|
||||
\f[\begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array}\f]
|
||||
When all the mask elements are 0's, the function returns
|
||||
mean=stddev=Scalar::all(0).
|
||||
@note The calculated standard deviation is only the diagonal of the
|
||||
|
||||
@ -323,11 +323,8 @@ struct Sum_SIMD<short, int>
|
||||
#endif
|
||||
|
||||
template<typename T, typename ST>
|
||||
static void sum_(const T* src0, const uchar* mask, ST* dst, int* nzm, int len, int cn, int mcn )
|
||||
static int sum_(const T* src0, const uchar* mask, ST* dst, int len, int cn )
|
||||
{
|
||||
for( int k = 0; k < mcn; k++ )
|
||||
nzm[k] = 0;
|
||||
|
||||
const T* src = src0;
|
||||
if( !mask )
|
||||
{
|
||||
@ -386,14 +383,10 @@ static void sum_(const T* src0, const uchar* mask, ST* dst, int* nzm, int len, i
|
||||
dst[k+2] = s2;
|
||||
dst[k+3] = s3;
|
||||
}
|
||||
|
||||
if (nzm)
|
||||
nzm[0] = len;
|
||||
return;
|
||||
return len;
|
||||
}
|
||||
|
||||
CV_Assert(mcn >= 1 && nzm);
|
||||
int i;
|
||||
int i, nzm = 0;
|
||||
if( cn == 1 )
|
||||
{
|
||||
ST s = dst[0];
|
||||
@ -401,112 +394,74 @@ static void sum_(const T* src0, const uchar* mask, ST* dst, int* nzm, int len, i
|
||||
if( mask[i] )
|
||||
{
|
||||
s += src[i];
|
||||
nzm[0]++;
|
||||
nzm++;
|
||||
}
|
||||
dst[0] = s;
|
||||
}
|
||||
else if( cn == 3 )
|
||||
{
|
||||
ST s0 = dst[0], s1 = dst[1], s2 = dst[2];
|
||||
if( mcn == 1 )
|
||||
{
|
||||
for( i = 0; i < len; i++, src += 3 )
|
||||
if( mask[i] )
|
||||
{
|
||||
s0 += src[0];
|
||||
s1 += src[1];
|
||||
s2 += src[2];
|
||||
nzm[0]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(mcn == cn);
|
||||
for( i = 0; i < len; i++, src += 3, mask += 3 )
|
||||
for( i = 0; i < len; i++, src += 3 )
|
||||
if( mask[i] )
|
||||
{
|
||||
if( mask[0] )
|
||||
{
|
||||
s0 += src[0];
|
||||
nzm[0]++;
|
||||
}
|
||||
if( mask[1] )
|
||||
{
|
||||
s1 += src[1];
|
||||
nzm[1]++;
|
||||
}
|
||||
if( mask[2] )
|
||||
{
|
||||
s2 += src[2];
|
||||
nzm[2]++;
|
||||
}
|
||||
s0 += src[0];
|
||||
s1 += src[1];
|
||||
s2 += src[2];
|
||||
nzm++;
|
||||
}
|
||||
}
|
||||
dst[0] = s0;
|
||||
dst[1] = s1;
|
||||
dst[2] = s2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mcn == 1 )
|
||||
{
|
||||
for( i = 0; i < len; i++, src += cn )
|
||||
if( mask[i] )
|
||||
for( i = 0; i < len; i++, src += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
int k = 0;
|
||||
#if CV_ENABLE_UNROLLED
|
||||
for( ; k <= cn - 4; k += 4 )
|
||||
{
|
||||
int k = 0;
|
||||
#if CV_ENABLE_UNROLLED
|
||||
for( ; k <= cn - 4; k += 4 )
|
||||
{
|
||||
ST s0, s1;
|
||||
s0 = dst[k] + src[k];
|
||||
s1 = dst[k+1] + src[k+1];
|
||||
dst[k] = s0; dst[k+1] = s1;
|
||||
s0 = dst[k+2] + src[k+2];
|
||||
s1 = dst[k+3] + src[k+3];
|
||||
dst[k+2] = s0; dst[k+3] = s1;
|
||||
}
|
||||
#endif
|
||||
for( ; k < cn; k++ )
|
||||
dst[k] += src[k];
|
||||
nzm[0]++;
|
||||
ST s0, s1;
|
||||
s0 = dst[k] + src[k];
|
||||
s1 = dst[k+1] + src[k+1];
|
||||
dst[k] = s0; dst[k+1] = s1;
|
||||
s0 = dst[k+2] + src[k+2];
|
||||
s1 = dst[k+3] + src[k+3];
|
||||
dst[k+2] = s0; dst[k+3] = s1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(mcn == cn);
|
||||
for( i = 0; i < len; i++, src += cn, mask += cn )
|
||||
for( int k = 0; k < cn; k++ )
|
||||
if( mask[k] )
|
||||
{
|
||||
dst[k] += src[k];
|
||||
nzm[k]++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; k < cn; k++ )
|
||||
dst[k] += src[k];
|
||||
nzm++;
|
||||
}
|
||||
}
|
||||
return nzm;
|
||||
}
|
||||
|
||||
|
||||
static void sum8u( const uchar* src, const uchar* mask, int* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum8u( const uchar* src, const uchar* mask, int* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
static void sum8s( const schar* src, const uchar* mask, int* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum8s( const schar* src, const uchar* mask, int* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
static void sum16u( const ushort* src, const uchar* mask, int* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum16u( const ushort* src, const uchar* mask, int* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
static void sum16s( const short* src, const uchar* mask, int* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum16s( const short* src, const uchar* mask, int* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
static void sum32s( const int* src, const uchar* mask, double* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum32s( const int* src, const uchar* mask, double* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
static void sum32f( const float* src, const uchar* mask, double* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum32f( const float* src, const uchar* mask, double* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
static void sum64f( const double* src, const uchar* mask, double* dst, int* nzm, int len, int cn, int mcn )
|
||||
{ sum_(src, mask, dst, nzm, len, cn, mcn); }
|
||||
static int sum64f( const double* src, const uchar* mask, double* dst, int len, int cn )
|
||||
{ return sum_(src, mask, dst, len, cn); }
|
||||
|
||||
typedef void (*SumFunc)(const uchar*, const uchar* mask, uchar*, int*, int, int, int);
|
||||
typedef int (*SumFunc)(const uchar*, const uchar* mask, uchar*, int, int);
|
||||
|
||||
static SumFunc getSumFunc(int depth)
|
||||
{
|
||||
@ -895,12 +850,10 @@ struct SumSqr_SIMD<schar, int, int>
|
||||
#endif
|
||||
|
||||
template<typename T, typename ST, typename SQT>
|
||||
static void sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
static int sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int len, int cn )
|
||||
{
|
||||
for( int k = 0; k < mcn; k++ )
|
||||
nzm[k] = 0;
|
||||
|
||||
const T* src = src0;
|
||||
|
||||
if( !mask )
|
||||
{
|
||||
SumSqr_SIMD<T, ST, SQT> vop;
|
||||
@ -967,14 +920,11 @@ static void sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int*
|
||||
sqsum[k] = sq0; sqsum[k+1] = sq1;
|
||||
sqsum[k+2] = sq2; sqsum[k+3] = sq3;
|
||||
}
|
||||
|
||||
if (nzm)
|
||||
nzm[0] = len;
|
||||
return;
|
||||
return len;
|
||||
}
|
||||
|
||||
CV_Assert(mcn >= 1 && nzm);
|
||||
int i;
|
||||
int i, nzm = 0;
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
ST s0 = sum[0];
|
||||
@ -984,7 +934,7 @@ static void sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int*
|
||||
{
|
||||
T v = src[i];
|
||||
s0 += v; sq0 += (SQT)v*v;
|
||||
nzm[0]++;
|
||||
nzm++;
|
||||
}
|
||||
sum[0] = s0;
|
||||
sqsum[0] = sq0;
|
||||
@ -993,113 +943,66 @@ static void sumsqr_(const T* src0, const uchar* mask, ST* sum, SQT* sqsum, int*
|
||||
{
|
||||
ST s0 = sum[0], s1 = sum[1], s2 = sum[2];
|
||||
SQT sq0 = sqsum[0], sq1 = sqsum[1], sq2 = sqsum[2];
|
||||
if( mcn == 1 )
|
||||
{
|
||||
for( i = 0; i < len; i++, src += 3 )
|
||||
if( mask[i] )
|
||||
{
|
||||
T v0 = src[0], v1 = src[1], v2 = src[2];
|
||||
s0 += v0; sq0 += (SQT)v0*v0;
|
||||
s1 += v1; sq1 += (SQT)v1*v1;
|
||||
s2 += v2; sq2 += (SQT)v2*v2;
|
||||
nzm[0]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(mcn == cn);
|
||||
for( i = 0; i < len; i++, src += 3, mask += 3 )
|
||||
for( i = 0; i < len; i++, src += 3 )
|
||||
if( mask[i] )
|
||||
{
|
||||
if( mask[0] )
|
||||
{
|
||||
T v0 = src[0];
|
||||
s0 += v0; sq0 += (SQT)v0*v0;
|
||||
nzm[0]++;
|
||||
}
|
||||
if( mask[1] )
|
||||
{
|
||||
T v1 = src[1];
|
||||
s1 += v1; sq1 += (SQT)v1*v1;
|
||||
nzm[1]++;
|
||||
}
|
||||
if( mask[2] )
|
||||
{
|
||||
T v2 = src[2];
|
||||
s2 += v2; sq2 += (SQT)v2*v2;
|
||||
nzm[2]++;
|
||||
}
|
||||
T v0 = src[0], v1 = src[1], v2 = src[2];
|
||||
s0 += v0; sq0 += (SQT)v0*v0;
|
||||
s1 += v1; sq1 += (SQT)v1*v1;
|
||||
s2 += v2; sq2 += (SQT)v2*v2;
|
||||
nzm++;
|
||||
}
|
||||
}
|
||||
sum[0] = s0; sum[1] = s1; sum[2] = s2;
|
||||
sqsum[0] = sq0; sqsum[1] = sq1; sqsum[2] = sq2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mcn == 1 )
|
||||
{
|
||||
for( i = 0; i < len; i++, src += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
for( int k = 0; k < cn; k++ )
|
||||
{
|
||||
T v = src[k];
|
||||
ST s = sum[k] + v;
|
||||
SQT sq = sqsum[k] + (SQT)v*v;
|
||||
sum[k] = s; sqsum[k] = sq;
|
||||
}
|
||||
nzm[0]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert(mcn == cn);
|
||||
for( i = 0; i < len; i++, src += cn, mask += cn )
|
||||
for( i = 0; i < len; i++, src += cn )
|
||||
if( mask[i] )
|
||||
{
|
||||
for( int k = 0; k < cn; k++ )
|
||||
if( mask[k] )
|
||||
{
|
||||
T v = src[k];
|
||||
ST s = sum[k] + v;
|
||||
SQT sq = sqsum[k] + (SQT)v*v;
|
||||
sum[k] = s; sqsum[k] = sq;
|
||||
nzm[k]++;
|
||||
}
|
||||
}
|
||||
{
|
||||
T v = src[k];
|
||||
ST s = sum[k] + v;
|
||||
SQT sq = sqsum[k] + (SQT)v*v;
|
||||
sum[k] = s; sqsum[k] = sq;
|
||||
}
|
||||
nzm++;
|
||||
}
|
||||
}
|
||||
return nzm;
|
||||
}
|
||||
|
||||
|
||||
static void sqsum8u( const uchar* src, const uchar* mask, int* sum, int* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum8u( const uchar* src, const uchar* mask, int* sum, int* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
static void sqsum8s( const schar* src, const uchar* mask, int* sum, int* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum8s( const schar* src, const uchar* mask, int* sum, int* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
static void sqsum16u( const ushort* src, const uchar* mask, int* sum, double* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum16u( const ushort* src, const uchar* mask, int* sum, double* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
static void sqsum16s( const short* src, const uchar* mask, int* sum, double* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum16s( const short* src, const uchar* mask, int* sum, double* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
static void sqsum32s( const int* src, const uchar* mask, double* sum, double* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum32s( const int* src, const uchar* mask, double* sum, double* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
static void sqsum32f( const float* src, const uchar* mask, double* sum, double* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum32f( const float* src, const uchar* mask, double* sum, double* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
static void sqsum64f( const double* src, const uchar* mask, double* sum, double* sqsum, int* nzm, int len, int cn, int mcn )
|
||||
{ sumsqr_(src, mask, sum, sqsum, nzm, len, cn, mcn); }
|
||||
static int sqsum64f( const double* src, const uchar* mask, double* sum, double* sqsum, int len, int cn )
|
||||
{ return sumsqr_(src, mask, sum, sqsum, len, cn); }
|
||||
|
||||
typedef int (*SumSqrFunc)(const uchar*, const uchar* mask, uchar*, uchar*, int*, int, int, int);
|
||||
typedef int (*SumSqrFunc)(const uchar*, const uchar* mask, uchar*, uchar*, int, int);
|
||||
|
||||
static SumSqrFunc getSumSqrTab(int depth)
|
||||
{
|
||||
static SumSqrFunc sumSqrTab[] =
|
||||
{
|
||||
(SumSqrFunc)GET_OPTIMIZED(sqsum8u), (SumSqrFunc)sqsum8s,
|
||||
(SumSqrFunc)sqsum16u, (SumSqrFunc)sqsum16s,
|
||||
(SumSqrFunc)sqsum32s,
|
||||
(SumSqrFunc)GET_OPTIMIZED(sqsum32f), (SumSqrFunc)sqsum64f,
|
||||
0
|
||||
(SumSqrFunc)GET_OPTIMIZED(sqsum8u), (SumSqrFunc)sqsum8s, (SumSqrFunc)sqsum16u, (SumSqrFunc)sqsum16s,
|
||||
(SumSqrFunc)sqsum32s, (SumSqrFunc)GET_OPTIMIZED(sqsum32f), (SumSqrFunc)sqsum64f, 0
|
||||
};
|
||||
|
||||
return sumSqrTab[depth];
|
||||
@ -1323,7 +1226,7 @@ cv::Scalar cv::sum( InputArray _src )
|
||||
for( j = 0; j < total; j += blockSize )
|
||||
{
|
||||
int bsz = std::min(total - j, blockSize);
|
||||
func( ptrs[0], 0, (uchar*)buf, 0, bsz, cn, 0 );
|
||||
func( ptrs[0], 0, (uchar*)buf, bsz, cn );
|
||||
count += bsz;
|
||||
if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
|
||||
{
|
||||
@ -1487,8 +1390,6 @@ namespace cv
|
||||
static bool ipp_mean( Mat &src, Mat &mask, Scalar &ret )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
if( mask.channels() > 1 )
|
||||
return false;
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
size_t total_size = src.total();
|
||||
@ -1584,10 +1485,11 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask )
|
||||
CV_INSTRUMENT_REGION()
|
||||
|
||||
Mat src = _src.getMat(), mask = _mask.getMat();
|
||||
int k, cn = src.channels(), depth = src.depth(), mcn = mask.channels();
|
||||
CV_Assert( mask.empty() || (mask.depth() == CV_8U && (mcn == 1 || mcn == cn)) );
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U );
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
Scalar s;
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_mean(src, mask, s), s)
|
||||
|
||||
SumFunc func = getSumFunc(depth);
|
||||
@ -1598,22 +1500,11 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask )
|
||||
uchar* ptrs[2];
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
int total = (int)it.size, blockSize = total, intSumBlockSize = 0;
|
||||
int j;
|
||||
AutoBuffer<int, 4> _count(mcn), _nz(mcn);
|
||||
int* count = _count;
|
||||
int* nz = _nz;
|
||||
AutoBuffer<int, 4> _buf;
|
||||
int j, count = 0;
|
||||
AutoBuffer<int> _buf;
|
||||
int* buf = (int*)&s[0];
|
||||
bool blockSum = depth <= CV_16S;
|
||||
size_t esz = 0, mesz = 0;
|
||||
AutoBuffer<size_t, 4> _nz0(mcn);
|
||||
size_t* nz0 = _nz0;
|
||||
|
||||
for( k = 0; k < mcn; k++ )
|
||||
{
|
||||
count[k] = 0;
|
||||
nz0[k] = 0;
|
||||
}
|
||||
size_t esz = 0, nz0 = 0;
|
||||
|
||||
if( blockSum )
|
||||
{
|
||||
@ -1625,7 +1516,6 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask )
|
||||
for( k = 0; k < cn; k++ )
|
||||
buf[k] = 0;
|
||||
esz = src.elemSize();
|
||||
mesz = mask.elemSize();
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
@ -1633,38 +1523,24 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask )
|
||||
for( j = 0; j < total; j += blockSize )
|
||||
{
|
||||
int bsz = std::min(total - j, blockSize);
|
||||
func( ptrs[0], ptrs[1], (uchar*)buf, nz, bsz, cn, mcn );
|
||||
|
||||
bool doCommit = false;
|
||||
for( k = 0; k < mcn; k++ )
|
||||
{
|
||||
nz0[k] += nz[k];
|
||||
count[k] += nz[k];
|
||||
if( count[k] + blockSize >= intSumBlockSize )
|
||||
doCommit = true;
|
||||
}
|
||||
if( blockSum && (doCommit || (i+1 >= it.nplanes && j+bsz >= total)) )
|
||||
int nz = func( ptrs[0], ptrs[1], (uchar*)buf, bsz, cn );
|
||||
count += nz;
|
||||
nz0 += nz;
|
||||
if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
|
||||
{
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
s[k] += buf[k];
|
||||
buf[k] = 0;
|
||||
}
|
||||
for( k = 0; k < mcn; k++ )
|
||||
count[k] = 0;
|
||||
count = 0;
|
||||
}
|
||||
ptrs[0] += bsz*esz;
|
||||
if( ptrs[1] )
|
||||
ptrs[1] += bsz*mesz;
|
||||
ptrs[1] += bsz;
|
||||
}
|
||||
}
|
||||
|
||||
if( mcn == cn )
|
||||
for( k = 0; k < cn; k++ )
|
||||
s[k] *= nz0[k] ? 1./nz0[k] : 0;
|
||||
else
|
||||
s *= nz0[0] ? 1./nz0[0] : 0;
|
||||
return s;
|
||||
return s*(nz0 ? 1./nz0 : 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
@ -1681,8 +1557,6 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv
|
||||
const int cn = _src.channels();
|
||||
if (cn > 4)
|
||||
return false;
|
||||
if (_mask.channels() > 1)
|
||||
return false;
|
||||
|
||||
{
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type);
|
||||
@ -1869,9 +1743,6 @@ static bool ipp_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& m
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
if( mask.channels() > 1 )
|
||||
return false;
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
int cn = src.channels();
|
||||
|
||||
@ -1995,14 +1866,14 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input
|
||||
ocl_meanStdDev(_src, _mean, _sdv, _mask))
|
||||
|
||||
Mat src = _src.getMat(), mask = _mask.getMat();
|
||||
int k, cn = src.channels(), depth = src.depth(), mcn = mask.channels();
|
||||
CV_Assert( mask.empty() || (mask.depth() == CV_8U && (mcn == 1 || mcn == cn)) );
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8UC1 );
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_MEAN_STDDEV>(src.cols, src.rows),
|
||||
openvx_meanStdDev(src, _mean, _sdv, mask))
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_meanStdDev(src, _mean, _sdv, mask));
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
|
||||
SumSqrFunc func = getSumSqrTab(depth);
|
||||
|
||||
@ -2012,23 +1883,12 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input
|
||||
uchar* ptrs[2];
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
int total = (int)it.size, blockSize = total, intSumBlockSize = 0;
|
||||
int j;
|
||||
AutoBuffer<int> _count(mcn), _nz(mcn);
|
||||
int* count = _count;
|
||||
int* nz = _nz;
|
||||
int j, count = 0, nz0 = 0;
|
||||
AutoBuffer<double> _buf(cn*4);
|
||||
double *s = (double*)_buf, *sq = s + cn;
|
||||
int *sbuf = (int*)s, *sqbuf = (int*)sq;
|
||||
bool blockSum = depth <= CV_16S, blockSqSum = depth <= CV_8S;
|
||||
size_t esz = 0, mesz = 0;
|
||||
AutoBuffer<size_t> _nz0(mcn);
|
||||
size_t* nz0 = _nz0;
|
||||
|
||||
for( k = 0; k < mcn; k++ )
|
||||
{
|
||||
count[k] = 0;
|
||||
nz0[k] = 0;
|
||||
}
|
||||
size_t esz = 0;
|
||||
|
||||
for( k = 0; k < cn; k++ )
|
||||
s[k] = sq[k] = 0;
|
||||
@ -2043,7 +1903,6 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input
|
||||
for( k = 0; k < cn; k++ )
|
||||
sbuf[k] = sqbuf[k] = 0;
|
||||
esz = src.elemSize();
|
||||
mesz = mask.elemSize();
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
@ -2051,17 +1910,10 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input
|
||||
for( j = 0; j < total; j += blockSize )
|
||||
{
|
||||
int bsz = std::min(total - j, blockSize);
|
||||
func( ptrs[0], ptrs[1], (uchar*)sbuf, (uchar*)sqbuf, nz, bsz, cn, mcn );
|
||||
|
||||
bool doCommit = false;
|
||||
for( k = 0; k < mcn; k++ )
|
||||
{
|
||||
nz0[k] += nz[k];
|
||||
count[k] += nz[k];
|
||||
if( count[k] + blockSize >= intSumBlockSize )
|
||||
doCommit = true;
|
||||
}
|
||||
if( blockSum && (doCommit || (i+1 >= it.nplanes && j+bsz >= total)) )
|
||||
int nz = func( ptrs[0], ptrs[1], (uchar*)sbuf, (uchar*)sqbuf, bsz, cn );
|
||||
count += nz;
|
||||
nz0 += nz;
|
||||
if( blockSum && (count + blockSize >= intSumBlockSize || (i+1 >= it.nplanes && j+bsz >= total)) )
|
||||
{
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
@ -2076,29 +1928,19 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input
|
||||
sqbuf[k] = 0;
|
||||
}
|
||||
}
|
||||
for( k = 0; k < mcn; k++ )
|
||||
count[k] = 0;
|
||||
count = 0;
|
||||
}
|
||||
ptrs[0] += bsz*esz;
|
||||
if( ptrs[1] )
|
||||
ptrs[1] += bsz*mesz;
|
||||
ptrs[1] += bsz;
|
||||
}
|
||||
}
|
||||
|
||||
if( mcn == cn )
|
||||
for( k = 0; k < cn; k++ ) {
|
||||
double scale = nz0[k] ? 1./nz0[k] : 0;
|
||||
s[k] *= scale;
|
||||
sq[k] = std::sqrt(std::max(sq[k]*scale - s[k]*s[k], 0.));
|
||||
}
|
||||
else
|
||||
double scale = nz0 ? 1./nz0 : 0.;
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
double scale = nz0[0] ? 1./nz0[0] : 0.;
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
s[k] *= scale;
|
||||
sq[k] = std::sqrt(std::max(sq[k]*scale - s[k]*s[k], 0.));
|
||||
}
|
||||
s[k] *= scale;
|
||||
sq[k] = std::sqrt(std::max(sq[k]*scale - s[k]*s[k], 0.));
|
||||
}
|
||||
|
||||
for( j = 0; j < 2; j++ )
|
||||
|
||||
@ -1162,7 +1162,7 @@ struct CartToPolarToCartOp : public BaseElemWiseOp
|
||||
|
||||
struct MeanOp : public BaseElemWiseOp
|
||||
{
|
||||
MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SUPPORT_MULTICHANNELMASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
|
||||
MeanOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
|
||||
{
|
||||
context = 3;
|
||||
};
|
||||
@ -1244,7 +1244,7 @@ struct MeanStdDevOp : public BaseElemWiseOp
|
||||
Scalar sqmeanRef;
|
||||
int cn;
|
||||
|
||||
MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SUPPORT_MULTICHANNELMASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
|
||||
MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
|
||||
{
|
||||
cn = 0;
|
||||
context = 7;
|
||||
|
||||
@ -2598,11 +2598,11 @@ void divide(const Mat& src1, const Mat& src2, Mat& dst, double scale)
|
||||
|
||||
|
||||
template<typename _Tp> static void
|
||||
mean_(const _Tp* src, const uchar* mask, size_t total, int cn, int mcn, Scalar& sum, Scalar_<int>& nz)
|
||||
mean_(const _Tp* src, const uchar* mask, size_t total, int cn, Scalar& sum, int& nz)
|
||||
{
|
||||
if( !mask )
|
||||
{
|
||||
nz += Scalar_<int>::all((int)total);
|
||||
nz += (int)total;
|
||||
total *= cn;
|
||||
for( size_t i = 0; i < total; i += cn )
|
||||
{
|
||||
@ -2610,41 +2610,23 @@ mean_(const _Tp* src, const uchar* mask, size_t total, int cn, int mcn, Scalar&
|
||||
sum[c] += src[i + c];
|
||||
}
|
||||
}
|
||||
else if( mcn == 1 )
|
||||
else
|
||||
{
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
if( mask[i] )
|
||||
{
|
||||
nz++;
|
||||
for( int c = 0; c < cn; c++ )
|
||||
{
|
||||
nz[c]++;
|
||||
sum[c] += src[i*cn + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
total *= cn;
|
||||
for( size_t i = 0; i < total; i += cn )
|
||||
{
|
||||
for( int c = 0; c < cn; c++ )
|
||||
{
|
||||
if( mask[i + c] )
|
||||
{
|
||||
nz[c]++;
|
||||
sum[c] += src[i + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scalar mean(const Mat& src, const Mat& mask)
|
||||
{
|
||||
CV_Assert(mask.empty() || (mask.depth() == CV_8U && mask.size == src.size &&
|
||||
(mask.channels() == 1 || mask.channels() == src.channels())));
|
||||
CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.size == src.size));
|
||||
Scalar sum;
|
||||
Scalar_<int> nz = Scalar_<int>::all(0);
|
||||
int nz = 0;
|
||||
|
||||
const Mat *arrays[]={&src, &mask, 0};
|
||||
Mat planes[2];
|
||||
@ -2652,7 +2634,7 @@ Scalar mean(const Mat& src, const Mat& mask)
|
||||
NAryMatIterator it(arrays, planes);
|
||||
size_t total = planes[0].total();
|
||||
size_t i, nplanes = it.nplanes;
|
||||
int c, depth = src.depth(), cn = src.channels(), mcn = mask.channels();
|
||||
int depth = src.depth(), cn = src.channels();
|
||||
|
||||
for( i = 0; i < nplanes; i++, ++it )
|
||||
{
|
||||
@ -2662,34 +2644,32 @@ Scalar mean(const Mat& src, const Mat& mask)
|
||||
switch( depth )
|
||||
{
|
||||
case CV_8U:
|
||||
mean_((const uchar*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const uchar*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
case CV_8S:
|
||||
mean_((const schar*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const schar*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
case CV_16U:
|
||||
mean_((const ushort*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const ushort*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
case CV_16S:
|
||||
mean_((const short*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const short*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
case CV_32S:
|
||||
mean_((const int*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const int*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
case CV_32F:
|
||||
mean_((const float*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const float*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
case CV_64F:
|
||||
mean_((const double*)sptr, mptr, total, cn, mcn, sum, nz);
|
||||
mean_((const double*)sptr, mptr, total, cn, sum, nz);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsUnsupportedFormat, "");
|
||||
}
|
||||
}
|
||||
|
||||
for( c = 0; c < cn; c++ )
|
||||
sum[c] *= (1./std::max(nz[c], 1));
|
||||
return sum;
|
||||
return sum * (1./std::max(nz, 1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user