mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 19:50:38 +08:00
united cv::Mat and cv::MatND
This commit is contained in:
parent
f6895e7738
commit
541441e85b
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -2794,7 +2794,6 @@ static inline void read(const FileNode& node, string& value, const string& defau
|
||||
}
|
||||
|
||||
CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
|
||||
CV_EXPORTS void read(const FileNode& node, MatND& mat, const MatND& default_mat=MatND() );
|
||||
CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );
|
||||
|
||||
inline FileNode::operator int() const
|
||||
|
@ -157,6 +157,11 @@ typedef unsigned short ushort;
|
||||
|
||||
typedef signed char schar;
|
||||
|
||||
/* special informative macros for wrapper generators */
|
||||
#define CV_OUT
|
||||
#define CV_CARRAY(counter)
|
||||
#define CV_METHOD
|
||||
|
||||
/* CvArr* is used to pass arbitrary
|
||||
* array-like data structures
|
||||
* into functions where the particular
|
||||
|
@ -399,11 +399,57 @@ bitwiseSOp_( const Mat& srcmat, Mat& dstmat, const Scalar& _scalar )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
binaryOp( const Mat& src1, const Mat& src2, Mat& dst, BinaryFunc func, int dsttype=-1 )
|
||||
{
|
||||
if( dsttype == -1 )
|
||||
dsttype = src1.type();
|
||||
CV_Assert( src1.type() == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, dsttype);
|
||||
const Mat* arrays[] = { &src1, &src2, &dst, 0 };
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func(it.planes[0], it.planes[1], it.planes[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
CV_Assert( src1.size() == src2.size() );
|
||||
dst.create( src1.size(), dsttype );
|
||||
func( src1, src2, dst );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
binaryMaskOp( const Mat& src1, const Mat& src2, Mat& dst,
|
||||
const Mat& mask, BinaryFunc func )
|
||||
{
|
||||
CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
|
||||
CV_Assert( src1.type() == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 };
|
||||
Mat planes[4];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
if( !mask.data )
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func(it.planes[0], it.planes[1], it.planes[2]);
|
||||
else
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
binaryMaskOp(it.planes[0], it.planes[1],
|
||||
it.planes[2], it.planes[3],
|
||||
func);
|
||||
return;
|
||||
}
|
||||
|
||||
CV_Assert( src1.size() == src2.size() );
|
||||
dst.create( src1.size(), src1.type() );
|
||||
|
||||
if( !mask.data )
|
||||
@ -436,6 +482,24 @@ binarySMaskOp( const Mat& src1, const Scalar& s, Mat& dst,
|
||||
const Mat& mask, BinarySFuncCn func )
|
||||
{
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( src1.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = { &src1, &dst, &mask, 0 };
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
if( !mask.data )
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func(it.planes[0], it.planes[1], s);
|
||||
else
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
binarySMaskOp(it.planes[0], s, it.planes[1],
|
||||
it.planes[2], func);
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create( src1.size(), src1.type() );
|
||||
|
||||
if( !mask.data )
|
||||
@ -499,6 +563,18 @@ void bitwise_xor(const Mat& a, const Scalar& s, Mat& c, const Mat& mask)
|
||||
|
||||
void bitwise_not(const Mat& src, Mat& dst)
|
||||
{
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
dst.create(src.dims, src.size, src.type());
|
||||
const Mat* arrays[] = { &src, &dst, 0 };
|
||||
Mat planes[4];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
bitwise_not(it.planes[0], it.planes[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
const uchar* sptr = src.data;
|
||||
dst.create( src.size(), src.type() );
|
||||
uchar* dptr = dst.data;
|
||||
@ -564,21 +640,50 @@ static BinaryFunc subTab[] =
|
||||
binaryOpC1_<OpSub<double>,NoVec>, 0
|
||||
};
|
||||
|
||||
|
||||
void add( const Mat& src1, const Mat& src2, Mat& dst )
|
||||
{
|
||||
Size size = src1.size(); int type = src1.type();
|
||||
int type = src1.type();
|
||||
BinaryFunc func = addTab[CV_MAT_DEPTH(type)];
|
||||
CV_Assert( size == src2.size() && type == src2.type() && func != 0 );
|
||||
CV_Assert( type == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], it.planes[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
Size size = src1.size();
|
||||
CV_Assert( size == src2.size() );
|
||||
dst.create( size, type );
|
||||
func(src1, src2, dst);
|
||||
}
|
||||
|
||||
void subtract( const Mat& src1, const Mat& src2, Mat& dst )
|
||||
{
|
||||
Size size = src1.size(); int type = src1.type();
|
||||
int type = src1.type();
|
||||
BinaryFunc func = subTab[CV_MAT_DEPTH(type)];
|
||||
CV_Assert( size == src2.size() && type == src2.type() && func != 0 );
|
||||
CV_Assert( type == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], it.planes[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
Size size = src1.size();
|
||||
CV_Assert( size == src2.size() );
|
||||
dst.create( size, type );
|
||||
func(src1, src2, dst);
|
||||
}
|
||||
@ -698,7 +803,21 @@ void multiply(const Mat& src1, const Mat& src2, Mat& dst, double scale)
|
||||
};
|
||||
|
||||
MulDivFunc func = tab[src1.depth()];
|
||||
CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
|
||||
CV_Assert( src1.type() == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], it.planes[2], scale );
|
||||
return;
|
||||
}
|
||||
|
||||
CV_Assert( src1.size() == src2.size() );
|
||||
dst.create( src1.size(), src1.type() );
|
||||
func( src1, src2, dst, scale );
|
||||
}
|
||||
@ -764,6 +883,20 @@ void divide(const Mat& src1, const Mat& src2, Mat& dst, double scale)
|
||||
|
||||
MulDivFunc func = tab[src1.depth()];
|
||||
CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], it.planes[2], scale );
|
||||
return;
|
||||
}
|
||||
|
||||
CV_Assert( src1.size() == src2.size() );
|
||||
dst.create( src1.size(), src1.type() );
|
||||
func( src1, src2, dst, scale );
|
||||
}
|
||||
@ -827,6 +960,19 @@ void divide(double scale, const Mat& src, Mat& dst)
|
||||
|
||||
RecipFunc func = tab[src.depth()];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
dst.create(src.dims, src.size, src.type());
|
||||
const Mat* arrays[] = {&src, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( scale, it.planes[0], it.planes[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create( src.size(), src.type() );
|
||||
func( scale, src, dst );
|
||||
}
|
||||
@ -983,7 +1129,21 @@ void addWeighted( const Mat& src1, double alpha, const Mat& src2,
|
||||
};
|
||||
|
||||
AddWeightedFunc func = tab[src1.depth()];
|
||||
CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
|
||||
CV_Assert( src1.type() == src2.type() && func != 0 );
|
||||
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], alpha, it.planes[1], beta, gamma, it.planes[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
CV_Assert( src1.size() == src2.size() );
|
||||
dst.create( src1.size(), src1.type() );
|
||||
func( src1, alpha, src2, beta, gamma, dst );
|
||||
}
|
||||
@ -1024,10 +1184,7 @@ void absdiff( const Mat& src1, const Mat& src2, Mat& dst )
|
||||
binaryOpC1_<OpAbsDiff<double>,NoVec>, 0
|
||||
};
|
||||
|
||||
dst.create(src1.size(), src1.type());
|
||||
BinaryFunc func = tab[src1.depth()];
|
||||
CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && func != 0);
|
||||
func( src1, src2, dst );
|
||||
binaryOp(src1, src2, dst, tab[src1.depth()]);
|
||||
}
|
||||
|
||||
|
||||
@ -1043,9 +1200,22 @@ void absdiff( const Mat& src1, const Scalar& s, Mat& dst )
|
||||
binarySOpCn_<OpAbsDiffS<double> >, 0
|
||||
};
|
||||
|
||||
dst.create(src1.size(), src1.type());
|
||||
BinarySFuncCn func = tab[src1.depth()];
|
||||
CV_Assert(src1.channels() <= 4 && func != 0);
|
||||
|
||||
if( src1.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], s );
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create(src1.size(), src1.type());
|
||||
func( src1, dst, s );
|
||||
}
|
||||
|
||||
@ -1174,13 +1344,24 @@ void inRange(const Mat& src, const Mat& lowerb,
|
||||
inRange_<InRangeC4<double, double> >, 0
|
||||
};
|
||||
|
||||
CV_Assert( src.size() == lowerb.size() && src.size() == upperb.size() &&
|
||||
src.type() == lowerb.type() && src.type() == upperb.type() &&
|
||||
src.channels() <= 4 );
|
||||
CV_Assert( src.type() == lowerb.type() && src.type() == upperb.type() && src.channels() <= 4 );
|
||||
|
||||
InRangeFunc func = tab[src.type()];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( src.dims > 2 || lowerb.dims > 2 || upperb.dims > 2 )
|
||||
{
|
||||
dst.create(src.dims, src.size, CV_8U);
|
||||
const Mat* arrays[] = {&src, &lowerb, &upperb, &dst, 0};
|
||||
Mat planes[4];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
|
||||
return;
|
||||
}
|
||||
|
||||
CV_Assert( src.size() == lowerb.size() && src.size() == upperb.size() );
|
||||
dst.create(src.size(), CV_8U);
|
||||
func( src, lowerb, upperb, dst );
|
||||
}
|
||||
@ -1224,6 +1405,18 @@ void inRange(const Mat& src, const Scalar& lowerb,
|
||||
InRangeSFunc func = tab[src.type()];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
dst.create(src.dims, src.size, CV_8U);
|
||||
const Mat* arrays[] = {&src, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], lowerb, upperb, it.planes[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create(src.size(), CV_8U);
|
||||
func( src, lowerb, upperb, dst );
|
||||
}
|
||||
@ -1275,8 +1468,7 @@ void compare( const Mat& src1, const Mat& src2, Mat& dst, int cmpOp )
|
||||
binaryOpC1_<CmpEQ<double>,NoVec>, 0},
|
||||
};
|
||||
|
||||
dst.create(src1.rows, src1.cols, CV_8U);
|
||||
CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && src1.channels() == 1);
|
||||
CV_Assert(src1.channels() == 1);
|
||||
|
||||
int depth = src1.depth();
|
||||
const Mat *psrc1 = &src1, *psrc2 = &src2;
|
||||
@ -1306,8 +1498,7 @@ void compare( const Mat& src1, const Mat& src2, Mat& dst, int cmpOp )
|
||||
}
|
||||
|
||||
BinaryFunc func = tab[cmpOp == CMP_EQ][depth];
|
||||
CV_Assert( func != 0 );
|
||||
func( *psrc1, *psrc2, dst );
|
||||
binaryOp(*psrc1, *psrc2, dst, func, CV_8U);
|
||||
if( invflag )
|
||||
bitwise_not(dst, dst);
|
||||
}
|
||||
@ -1368,6 +1559,23 @@ void compare( const Mat& src1, double value, Mat& dst, int cmpOp )
|
||||
|
||||
BinarySFuncC1 func = tab[cmpOp == CMP_EQ ? 0 : cmpOp == CMP_GT ? 1 : 2][depth];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( src1.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, CV_8U);
|
||||
const Mat* arrays[] = {&src1, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
func( it.planes[0], it.planes[1], value );
|
||||
if( invflag )
|
||||
bitwise_not(it.planes[2], it.planes[2]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
func( src1, dst, value );
|
||||
if( invflag )
|
||||
bitwise_not(dst, dst);
|
||||
@ -1405,11 +1613,7 @@ void min( const Mat& src1, const Mat& src2, Mat& dst )
|
||||
binaryOpC1_<MinOp<float>,VMin32f>, binaryOpC1_<MinOp<double>,NoVec>, 0
|
||||
};
|
||||
|
||||
BinaryFunc func = tab[src1.depth()];
|
||||
CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && func != 0);
|
||||
dst.create(src1.size(), src1.type());
|
||||
|
||||
return func( src1, src2, dst );
|
||||
binaryOp(src1, src2, dst, tab[src1.depth()]);
|
||||
}
|
||||
|
||||
void max( const Mat& src1, const Mat& src2, Mat& dst )
|
||||
@ -1421,11 +1625,7 @@ void max( const Mat& src1, const Mat& src2, Mat& dst )
|
||||
binaryOpC1_<MaxOp<float>,VMax32f>, binaryOpC1_<MaxOp<double>,NoVec>, 0
|
||||
};
|
||||
|
||||
BinaryFunc func = tab[src1.depth()];
|
||||
CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && func != 0);
|
||||
dst.create(src1.size(), src1.type());
|
||||
|
||||
return func( src1, src2, dst );
|
||||
binaryOp(src1, src2, dst, tab[src1.depth()]);
|
||||
}
|
||||
|
||||
void min( const Mat& src1, double value, Mat& dst )
|
||||
@ -1442,6 +1642,19 @@ void min( const Mat& src1, double value, Mat& dst )
|
||||
|
||||
BinarySFuncC1 func = tab[src1.depth()];
|
||||
CV_Assert(func != 0);
|
||||
|
||||
if( src1.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], value );
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create(src1.size(), src1.type());
|
||||
return func( src1, dst, value );
|
||||
}
|
||||
@ -1460,6 +1673,19 @@ void max( const Mat& src1, double value, Mat& dst )
|
||||
|
||||
BinarySFuncC1 func = tab[src1.depth()];
|
||||
CV_Assert(func != 0);
|
||||
|
||||
if( src1.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], it.planes[1], value );
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create(src1.size(), src1.type());
|
||||
return func( src1, dst, value );
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ void split(const Mat& src, Mat* mv)
|
||||
};
|
||||
|
||||
int i, depth = src.depth(), cn = src.channels();
|
||||
Size size = src.size();
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
@ -129,17 +128,31 @@ void split(const Mat& src, Mat* mv)
|
||||
}
|
||||
|
||||
for( i = 0; i < cn; i++ )
|
||||
mv[i].create(src.size(), depth);
|
||||
mv[i].create(src.dims, src.size, depth);
|
||||
|
||||
if( cn <= 4 )
|
||||
{
|
||||
SplitFunc func = tab[(cn-2)*5 + (src.elemSize1()>>1)];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[5];
|
||||
Mat planes[5];
|
||||
arrays[0] = &src;
|
||||
for( i = 0; i < cn; i++ )
|
||||
arrays[i+1] = &mv[i];
|
||||
NAryMatIterator it(arrays, planes, cn+1);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func( it.planes[0], &it.planes[1] );
|
||||
}
|
||||
else
|
||||
func( src, mv );
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<int> pairs(cn*2);
|
||||
AutoBuffer<int> pairs(cn*2);
|
||||
|
||||
for( i = 0; i < cn; i++ )
|
||||
{
|
||||
@ -216,7 +229,7 @@ mergeC4_( const Mat* srcmat, Mat& dstmat )
|
||||
|
||||
typedef void (*MergeFunc)(const Mat* src, Mat& dst);
|
||||
|
||||
void merge(const Mat* mv, size_t n, Mat& dst)
|
||||
void merge(const Mat* mv, size_t _n, Mat& dst)
|
||||
{
|
||||
static MergeFunc tab[] =
|
||||
{
|
||||
@ -225,18 +238,15 @@ void merge(const Mat* mv, size_t n, Mat& dst)
|
||||
mergeC4_<uchar>, mergeC4_<ushort>, mergeC4_<int>, 0, mergeC4_<int64>
|
||||
};
|
||||
|
||||
size_t i;
|
||||
CV_Assert( mv && n > 0 );
|
||||
CV_Assert( mv && _n > 0 );
|
||||
|
||||
int depth = mv[0].depth();
|
||||
bool allch1 = true;
|
||||
int total = 0;
|
||||
|
||||
Size size = mv[0].size();
|
||||
int i, total = 0, n = (int)_n;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
CV_Assert(mv[i].size() == size && mv[i].depth() == depth);
|
||||
CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth);
|
||||
allch1 = allch1 && mv[i].channels() == 1;
|
||||
total += mv[i].channels();
|
||||
}
|
||||
@ -249,17 +259,30 @@ void merge(const Mat* mv, size_t n, Mat& dst)
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create(size, CV_MAKETYPE(depth, total));
|
||||
dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, total));
|
||||
|
||||
if( allch1 && total <= 4 )
|
||||
{
|
||||
MergeFunc func = tab[(total-2)*5 + (CV_ELEM_SIZE(depth)>>1)];
|
||||
CV_Assert( func != 0 );
|
||||
if( mv[0].dims > 2 )
|
||||
{
|
||||
const Mat* arrays[5];
|
||||
Mat planes[5];
|
||||
arrays[total] = &dst;
|
||||
for( i = 0; i < total; i++ )
|
||||
arrays[i] = &mv[i];
|
||||
NAryMatIterator it(arrays, planes, total+1);
|
||||
|
||||
for( i = 0; i < it.nplanes; i++, ++it )
|
||||
func( &it.planes[0], it.planes[total] );
|
||||
}
|
||||
else
|
||||
func( mv, dst );
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<int> pairs(total*2);
|
||||
AutoBuffer<int> pairs(total*2);
|
||||
int j, k, ni=0;
|
||||
|
||||
for( i = 0, j = 0; i < n; i++, j += ni )
|
||||
@ -335,12 +358,28 @@ typedef void (*MixChannelsFunc)( const void** src, const int* sdelta0,
|
||||
|
||||
void mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs )
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
if( npairs == 0 )
|
||||
return;
|
||||
CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 );
|
||||
|
||||
if( src[0].dims > 2 )
|
||||
{
|
||||
size_t k, m = nsrcs, n = ndsts;
|
||||
CV_Assert( n > 0 && m > 0 );
|
||||
AutoBuffer<const Mat*> v(m + n);
|
||||
AutoBuffer<Mat> planes(m + n);
|
||||
for( k = 0; k < m; k++ )
|
||||
v[k] = &src[k];
|
||||
for( k = 0; k < n; k++ )
|
||||
v[m + k] = &dst[k];
|
||||
NAryMatIterator it(v, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
mixChannels( &it.planes[0], m, &it.planes[m], n, fromTo, npairs );
|
||||
return;
|
||||
}
|
||||
|
||||
size_t i, j;
|
||||
int depth = dst[0].depth(), esz1 = (int)dst[0].elemSize1();
|
||||
Size size = dst[0].size();
|
||||
|
||||
@ -704,21 +743,45 @@ void Mat::convertTo(Mat& dst, int _type, double alpha, double beta) const
|
||||
|
||||
Mat temp;
|
||||
const Mat* psrc = this;
|
||||
if( sdepth != ddepth && psrc == &dst )
|
||||
if( sdepth != ddepth && data == dst.data )
|
||||
psrc = &(temp = *this);
|
||||
|
||||
dst.create( size(), _type );
|
||||
CvtFunc func = 0;
|
||||
CvtScaleFunc scaleFunc = 0;
|
||||
|
||||
if( noScale )
|
||||
{
|
||||
CvtFunc func = tab[sdepth][ddepth];
|
||||
func = tab[sdepth][ddepth];
|
||||
CV_Assert( func != 0 );
|
||||
func( *psrc, dst );
|
||||
}
|
||||
else
|
||||
{
|
||||
CvtScaleFunc func = stab[sdepth][ddepth];
|
||||
CV_Assert( func != 0 );
|
||||
func( *psrc, dst, alpha, beta );
|
||||
scaleFunc = stab[sdepth][ddepth];
|
||||
CV_Assert( scaleFunc != 0 );
|
||||
}
|
||||
|
||||
if( dims <= 2 )
|
||||
{
|
||||
dst.create( size(), _type );
|
||||
if( func )
|
||||
func( *psrc, dst );
|
||||
else
|
||||
scaleFunc( *psrc, dst, alpha, beta );
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.create( dims, size, _type );
|
||||
const Mat* arrays[] = {psrc, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if( func )
|
||||
func(it.planes[0], it.planes[1]);
|
||||
else
|
||||
scaleFunc(it.planes[0], it.planes[1], alpha, beta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,21 @@ void Mat::copyTo( Mat& dst ) const
|
||||
if( data == dst.data )
|
||||
return;
|
||||
|
||||
if( dims > 2 )
|
||||
{
|
||||
dst.create( dims, size, type() );
|
||||
const Mat* arrays[] = { this, &dst, 0 };
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
CV_DbgAssert(it.planes[0].isContinuous() &&
|
||||
it.planes[1].isContinuous());
|
||||
size_t planeSize = it.planes[0].elemSize()*it.planes[0].rows*it.planes[0].cols;
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
memcpy(it.planes[1].data, it.planes[0].data, planeSize);
|
||||
return;
|
||||
}
|
||||
|
||||
dst.create( rows, cols, type() );
|
||||
Size sz = size();
|
||||
const uchar* sptr = data;
|
||||
@ -193,6 +208,18 @@ void Mat::copyTo( Mat& dst, const Mat& mask ) const
|
||||
return;
|
||||
}
|
||||
|
||||
if( dims > 2 )
|
||||
{
|
||||
dst.create( dims, size, type() );
|
||||
const Mat* arrays[] = { this, &dst, &mask, 0 };
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
it.planes[0].copyTo(it.planes[1], it.planes[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
uchar* data0 = dst.data;
|
||||
dst.create( size(), type() );
|
||||
if( dst.data != data0 ) // do not leave dst uninitialized
|
||||
@ -202,6 +229,17 @@ void Mat::copyTo( Mat& dst, const Mat& mask ) const
|
||||
|
||||
Mat& Mat::operator = (const Scalar& s)
|
||||
{
|
||||
if( dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = { this, 0 };
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
it.planes[0] = s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Size sz = size();
|
||||
uchar* dst = data;
|
||||
|
||||
@ -256,6 +294,17 @@ Mat& Mat::setTo(const Scalar& s, const Mat& mask)
|
||||
CV_Assert( func != 0 );
|
||||
double buf[4];
|
||||
scalarToRawData(s, buf, type(), 0);
|
||||
|
||||
if( dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = { this, &mask, 0 };
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
func(buf, it.planes[0], it.planes[1]);
|
||||
}
|
||||
else
|
||||
func(buf, *this, mask);
|
||||
}
|
||||
return *this;
|
||||
@ -379,6 +428,7 @@ void flip( const Mat& src, Mat& dst, int flip_mode )
|
||||
flipHoriz_<Vec<int64,4> > // 32
|
||||
};
|
||||
|
||||
CV_Assert( src.dims <= 2 );
|
||||
dst.create( src.size(), src.type() );
|
||||
|
||||
if( flip_mode == 0 )
|
||||
@ -405,6 +455,8 @@ void flip( const Mat& src, Mat& dst, int flip_mode )
|
||||
|
||||
void repeat(const Mat& src, int ny, int nx, Mat& dst)
|
||||
{
|
||||
CV_Assert( src.dims <= 2 );
|
||||
|
||||
dst.create(src.rows*ny, src.cols*nx, src.type());
|
||||
Size ssize = src.size(), dsize = dst.size();
|
||||
int esz = (int)src.elemSize();
|
||||
|
@ -347,6 +347,18 @@ static CvStatus CV_STDCALL Sqrt_64f(const double* src, double* dst, int len)
|
||||
|
||||
void magnitude( const Mat& X, const Mat& Y, Mat& Mag )
|
||||
{
|
||||
if( X.dims > 2 )
|
||||
{
|
||||
Mag.create(X.dims, X.size, X.type());
|
||||
const Mat* arrays[] = {&X, &Y, &Mag, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
magnitude( it.planes[0], it.planes[1], it.planes[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
int type = X.type(), depth = X.depth(), cn = X.channels();
|
||||
CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
|
||||
Mag.create( X.size(), type );
|
||||
@ -377,6 +389,18 @@ void magnitude( const Mat& X, const Mat& Y, Mat& Mag )
|
||||
|
||||
void phase( const Mat& X, const Mat& Y, Mat& Angle, bool angleInDegrees )
|
||||
{
|
||||
if( X.dims > 2 )
|
||||
{
|
||||
Angle.create(X.dims, X.size, X.type());
|
||||
const Mat* arrays[] = {&X, &Y, &Angle, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
phase( it.planes[0], it.planes[1], it.planes[2], angleInDegrees );
|
||||
return;
|
||||
}
|
||||
|
||||
float buf[2][MAX_BLOCK_SIZE];
|
||||
int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
|
||||
|
||||
@ -422,6 +446,19 @@ void phase( const Mat& X, const Mat& Y, Mat& Angle, bool angleInDegrees )
|
||||
|
||||
void cartToPolar( const Mat& X, const Mat& Y, Mat& Mag, Mat& Angle, bool angleInDegrees )
|
||||
{
|
||||
if( X.dims > 2 )
|
||||
{
|
||||
Mag.create(X.dims, X.size, X.type());
|
||||
Angle.create(X.dims, X.size, X.type());
|
||||
const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0};
|
||||
Mat planes[4];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
cartToPolar( it.planes[0], it.planes[1], it.planes[2], it.planes[2], angleInDegrees );
|
||||
return;
|
||||
}
|
||||
|
||||
float buf[2][MAX_BLOCK_SIZE];
|
||||
int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
|
||||
|
||||
@ -568,6 +605,19 @@ SinCos_32f( const float *angle,float *sinval, float* cosval,
|
||||
|
||||
void polarToCart( const Mat& Mag, const Mat& Angle, Mat& X, Mat& Y, bool angleInDegrees )
|
||||
{
|
||||
if( Mag.dims > 2 )
|
||||
{
|
||||
X.create(Mag.dims, Mag.size, Mag.type());
|
||||
Y.create(Mag.dims, Mag.size, Mag.type());
|
||||
const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
|
||||
Mat planes[4];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
polarToCart( it.planes[0], it.planes[1], it.planes[2], it.planes[2], angleInDegrees );
|
||||
return;
|
||||
}
|
||||
|
||||
int i, j, type = Angle.type(), depth = Angle.depth();
|
||||
Size size;
|
||||
|
||||
@ -1115,6 +1165,18 @@ static CvStatus CV_STDCALL Exp_64f( const double *_x, double *y, int n )
|
||||
|
||||
void exp( const Mat& src, Mat& dst )
|
||||
{
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
dst.create(src.dims, src.size, src.type());
|
||||
const Mat* arrays[] = {&src, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
exp( it.planes[0], it.planes[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
int depth = src.depth();
|
||||
dst.create( src.size(), src.type() );
|
||||
Size size = getContinuousSize( src, dst, src.channels() );
|
||||
@ -1756,6 +1818,18 @@ static CvStatus CV_STDCALL Log_64f( const double *x, double *y, int n )
|
||||
|
||||
void log( const Mat& src, Mat& dst )
|
||||
{
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
dst.create(src.dims, src.size, src.type());
|
||||
const Mat* arrays[] = {&src, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
log( it.planes[0], it.planes[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
int depth = src.depth();
|
||||
dst.create( src.size(), src.type() );
|
||||
Size size = getContinuousSize( src, dst, src.channels() );
|
||||
@ -1804,6 +1878,18 @@ typedef CvStatus (CV_STDCALL * IPowFunc)( const void* src, void* dst, int len, i
|
||||
|
||||
void pow( const Mat& _src, double power, Mat& dst )
|
||||
{
|
||||
if( _src.dims > 2 )
|
||||
{
|
||||
dst.create(_src.dims, _src.size, _src.type());
|
||||
const Mat* arrays[] = {&_src, &dst, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
pow( it.planes[0], power, it.planes[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
int ipower = cvRound( power ), i, j;
|
||||
bool is_ipower = 0;
|
||||
int depth = _src.depth();
|
||||
@ -1913,6 +1999,23 @@ void sqrt(const Mat& a, Mat& b)
|
||||
bool checkRange(const Mat& src, bool quiet, Point* pt,
|
||||
double minVal, double maxVal)
|
||||
{
|
||||
if( src.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&src, 0};
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if( !checkRange( it.planes[0], quiet, pt, minVal, maxVal ))
|
||||
{
|
||||
// todo: set index properly
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int depth = src.depth();
|
||||
Point badPt(-1, -1);
|
||||
double badValue = 0;
|
||||
@ -2263,6 +2366,7 @@ cvSolveCubic( const CvMat* coeffs, CvMat* roots )
|
||||
|
||||
int cv::solveCubic( const Mat& coeffs, Mat& roots )
|
||||
{
|
||||
CV_Assert( coeffs.dims <= 2 );
|
||||
const int n = 3;
|
||||
if( ((roots.rows != 1 || roots.cols != n) &&
|
||||
(roots.rows != n || roots.cols != 1)) ||
|
||||
@ -2289,7 +2393,8 @@ double cv::solvePoly( const Mat& coeffs0, Mat& roots0, int maxIters )
|
||||
double maxDiff = 0;
|
||||
int iter, i, j, n;
|
||||
|
||||
CV_Assert( (coeffs0.cols == 1 || coeffs0.rows == 1) &&
|
||||
CV_Assert( coeffs0.dims <= 2 &&
|
||||
(coeffs0.cols == 1 || coeffs0.rows == 1) &&
|
||||
(coeffs0.depth() == CV_32F || coeffs0.depth() == CV_64F) &&
|
||||
coeffs0.channels() <= 2 );
|
||||
n = coeffs0.cols + coeffs0.rows - 2;
|
||||
|
@ -989,7 +989,7 @@ void gemm( const Mat& matA, const Mat& matB, double alpha,
|
||||
GEMMStoreFunc storeFunc;
|
||||
Mat *matD = &D, tmat;
|
||||
const uchar* Cdata = C ? C->data : 0;
|
||||
size_t Cstep = C ? C->step : 0;
|
||||
size_t Cstep = C ? (size_t)C->step : 0;
|
||||
AutoBuffer<uchar> buf;
|
||||
|
||||
if( type == CV_32FC1 )
|
||||
@ -2058,6 +2058,18 @@ void perspectiveTransform( const Mat& src, Mat& dst, const Mat& _m )
|
||||
|
||||
void scaleAdd( const Mat& src1, double alpha, const Mat& src2, Mat& dst )
|
||||
{
|
||||
if( src1.dims > 2 || src2.dims > 2 )
|
||||
{
|
||||
dst.create(src1.dims, src1.size, src1.type());
|
||||
const Mat* arrays[] = {&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
scaleAdd( it.planes[0], alpha, it.planes[1], it.planes[2] );
|
||||
return;
|
||||
}
|
||||
|
||||
int type = src1.type(), depth = CV_MAT_DEPTH(type);
|
||||
CV_Assert( src1.size() == src2.size() && type == src2.type() );
|
||||
dst.create( src1.size(), type );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5266,14 +5266,16 @@ void writeScalar(FileStorage& fs, const string& value )
|
||||
|
||||
void write( FileStorage& fs, const string& name, const Mat& value )
|
||||
{
|
||||
if( value.dims <= 2 )
|
||||
{
|
||||
CvMat mat = value;
|
||||
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
|
||||
}
|
||||
|
||||
void write( FileStorage& fs, const string& name, const MatND& value )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
CvMatND mat = value;
|
||||
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: the 4 functions below need to be implemented more efficiently
|
||||
@ -5301,21 +5303,22 @@ void read( const FileNode& node, Mat& mat, const Mat& default_mat )
|
||||
default_mat.copyTo(mat);
|
||||
return;
|
||||
}
|
||||
Ptr<CvMat> m = (CvMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
|
||||
CV_Assert(CV_IS_MAT(m));
|
||||
Mat(m).copyTo(mat);
|
||||
}
|
||||
|
||||
void read( const FileNode& node, MatND& mat, const MatND& default_mat )
|
||||
{
|
||||
if( node.empty() )
|
||||
void* obj = cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
|
||||
if(CV_IS_MAT(obj))
|
||||
{
|
||||
default_mat.copyTo(mat);
|
||||
return;
|
||||
Mat((const CvMat*)obj).copyTo(mat);
|
||||
cvReleaseMat((CvMat**)&obj);
|
||||
}
|
||||
else if(CV_IS_MATND(obj))
|
||||
{
|
||||
Mat((const CvMatND*)obj).copyTo(mat);
|
||||
cvReleaseMatND((CvMatND**)&obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
cvRelease(&obj);
|
||||
CV_Error(CV_StsBadArg, "Unknown array type");
|
||||
}
|
||||
Ptr<CvMatND> m = (CvMatND*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
|
||||
CV_Assert(CV_IS_MATND(m));
|
||||
MatND(m).copyTo(mat);
|
||||
}
|
||||
|
||||
void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat )
|
||||
|
@ -588,15 +588,18 @@ void RNG::fill( Mat& mat, int disttype, const Scalar& param1, const Scalar& para
|
||||
}
|
||||
|
||||
CV_Assert( func != 0);
|
||||
func( mat, &state, param );
|
||||
}
|
||||
|
||||
void RNG::fill( MatND& mat, int disttype, const Scalar& param1, const Scalar& param2 )
|
||||
{
|
||||
NAryMatNDIterator it(mat);
|
||||
if( mat.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&mat, 0};
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
fill( it.planes[0], disttype, param1, param2 );
|
||||
func( it.planes[0], &state, param );
|
||||
}
|
||||
else
|
||||
func( mat, &state, param );
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -160,14 +160,23 @@ Scalar sum( const Mat& m )
|
||||
sum_<Vec<double, 4>, Vec<double, 4> >, 0
|
||||
};
|
||||
|
||||
Size size = m.size();
|
||||
SumFunc func;
|
||||
|
||||
CV_Assert( m.channels() <= 4 );
|
||||
|
||||
func = tab[m.type()];
|
||||
SumFunc func = tab[m.type()];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( m.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&m, 0};
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
Scalar s;
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
s += func(it.planes[0]);
|
||||
return s;
|
||||
}
|
||||
|
||||
return func(m);
|
||||
}
|
||||
|
||||
@ -208,6 +217,19 @@ int countNonZero( const Mat& m )
|
||||
|
||||
CountNonZeroFunc func = tab[m.depth()];
|
||||
CV_Assert( m.channels() == 1 && func != 0 );
|
||||
|
||||
if( m.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&m, 0};
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
int nz = 0;
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
nz += func(it.planes[0]);
|
||||
return nz;
|
||||
}
|
||||
|
||||
return func(m);
|
||||
}
|
||||
|
||||
@ -275,7 +297,7 @@ typedef Scalar (*MeanMaskFunc)(const Mat& src, const Mat& mask);
|
||||
|
||||
Scalar mean(const Mat& m)
|
||||
{
|
||||
return sum(m)*(1./std::max(m.rows*m.cols, 1));
|
||||
return sum(m)*(1./m.total());
|
||||
}
|
||||
|
||||
Scalar mean( const Mat& m, const Mat& mask )
|
||||
@ -314,11 +336,28 @@ Scalar mean( const Mat& m, const Mat& mask )
|
||||
if( !mask.data )
|
||||
return mean(m);
|
||||
|
||||
CV_Assert( m.channels() <= 4 && m.size() == mask.size() && mask.type() == CV_8U );
|
||||
CV_Assert( m.channels() <= 4 && mask.type() == CV_8U );
|
||||
|
||||
MeanMaskFunc func = tab[m.type()];
|
||||
CV_Assert( func != 0 );
|
||||
|
||||
if( m.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&m, &mask, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
double total = 0;
|
||||
Scalar s;
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
int n = countNonZero(it.planes[1]);
|
||||
s += mean(it.planes[0], it.planes[1])*(double)n;
|
||||
total += n;
|
||||
}
|
||||
return (s * 1./std::max(total, 1.));
|
||||
}
|
||||
|
||||
CV_Assert( m.size() == mask.size() );
|
||||
return func( m, mask );
|
||||
}
|
||||
|
||||
@ -510,20 +549,57 @@ void meanStdDev( const Mat& m, Scalar& mean, Scalar& stddev, const Mat& mask )
|
||||
meanStdDevMask_<SqrC4<double, double> >, 0
|
||||
};
|
||||
|
||||
CV_Assert( m.channels() <= 4 );
|
||||
CV_Assert( m.channels() <= 4 && (mask.empty() || mask.type() == CV_8U) );
|
||||
|
||||
if( !mask.data )
|
||||
{
|
||||
MeanStdDevFunc func = tab[m.type()];
|
||||
CV_Assert( func != 0 );
|
||||
func( m, mean, stddev );
|
||||
MeanStdDevMaskFunc mfunc = mtab[m.type()];
|
||||
CV_Assert( func != 0 || mfunc != 0 );
|
||||
|
||||
if( m.dims > 2 )
|
||||
{
|
||||
Scalar s, sq;
|
||||
double total = 0;
|
||||
|
||||
const Mat* arrays[] = {&m, &mask, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
int k, cn = m.channels();
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
Scalar _mean, _stddev;
|
||||
double nz = (double)(mask.data ? countNonZero(it.planes[1]) : it.planes[0].rows*it.planes[0].cols);
|
||||
|
||||
if( func )
|
||||
func(it.planes[0], _mean, _stddev);
|
||||
else
|
||||
mfunc(it.planes[0], it.planes[1], _mean, _stddev);
|
||||
|
||||
total += nz;
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
s[k] += _mean[k]*nz;
|
||||
sq[k] += (_stddev[k]*_stddev[k] + _mean[k]*_mean[k])*nz;
|
||||
}
|
||||
}
|
||||
|
||||
mean = stddev = Scalar();
|
||||
total = 1./std::max(total, 1.);
|
||||
for( k = 0; k < cn; k++ )
|
||||
{
|
||||
mean[k] = s[k]*total;
|
||||
stddev[k] = std::sqrt(std::max(sq[k]*total - mean[k]*mean[k], 0.));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( mask.data )
|
||||
{
|
||||
CV_Assert( mask.size() == m.size() );
|
||||
mfunc( m, mask, mean, stddev );
|
||||
}
|
||||
else
|
||||
{
|
||||
MeanStdDevMaskFunc func = mtab[m.type()];
|
||||
CV_Assert( mask.size() == m.size() && mask.type() == CV_8U && func != 0 );
|
||||
func( m, mask, mean, stddev );
|
||||
}
|
||||
func( m, mean, stddev );
|
||||
}
|
||||
|
||||
|
||||
@ -630,6 +706,8 @@ typedef void (*MinMaxIndxMaskFunc)(const Mat&, const Mat&,
|
||||
void minMaxLoc( const Mat& img, double* minVal, double* maxVal,
|
||||
Point* minLoc, Point* maxLoc, const Mat& mask )
|
||||
{
|
||||
CV_Assert(img.dims <= 2);
|
||||
|
||||
static MinMaxIndxFunc tab[] =
|
||||
{minMaxIndx_<uchar>, 0, minMaxIndx_<ushort>, minMaxIndx_<short>,
|
||||
minMaxIndx_<int>, minMaxIndx_<float>, minMaxIndx_<double>, 0};
|
||||
@ -683,6 +761,64 @@ void minMaxLoc( const Mat& img, double* minVal, double* maxVal,
|
||||
}
|
||||
}
|
||||
|
||||
static void ofs2idx(const Mat& a, size_t ofs, int* idx)
|
||||
{
|
||||
int i, d = a.dims;
|
||||
for( i = 0; i < d; i++ )
|
||||
{
|
||||
idx[i] = (int)(ofs / a.step[i]);
|
||||
ofs %= a.step[i];
|
||||
}
|
||||
}
|
||||
|
||||
void minMaxIndx(const Mat& a, double* minVal,
|
||||
double* maxVal, int* minIdx, int* maxIdx,
|
||||
const Mat& mask)
|
||||
{
|
||||
if( a.dims <= 2 )
|
||||
{
|
||||
Point minLoc, maxLoc;
|
||||
minMaxLoc(a, minVal, maxVal, &minLoc, &maxLoc, mask);
|
||||
if( minIdx )
|
||||
minIdx[0] = minLoc.x, minIdx[1] = minLoc.y;
|
||||
if( maxIdx )
|
||||
maxIdx[0] = maxLoc.x, maxIdx[1] = maxLoc.y;
|
||||
return;
|
||||
}
|
||||
|
||||
const Mat* arrays[] = {&a, &mask, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
double minval = DBL_MAX, maxval = -DBL_MAX;
|
||||
size_t minofs = 0, maxofs = 0, esz = a.elemSize();
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
double val0 = 0, val1 = 0;
|
||||
Point pt0, pt1;
|
||||
minMaxLoc( it.planes[0], &val0, &val1, &pt0, &pt1, it.planes[1] );
|
||||
if( val0 < minval )
|
||||
{
|
||||
minval = val0;
|
||||
minofs = (it.planes[0].data - a.data) + pt0.x*esz;
|
||||
}
|
||||
if( val1 > maxval )
|
||||
{
|
||||
maxval = val1;
|
||||
maxofs = (it.planes[0].data - a.data) + pt1.x*esz;
|
||||
}
|
||||
}
|
||||
|
||||
if( minVal )
|
||||
*minVal = minval;
|
||||
if( maxVal )
|
||||
*maxVal = maxval;
|
||||
if( minIdx )
|
||||
ofs2idx(a, minofs, minIdx);
|
||||
if( maxIdx )
|
||||
ofs2idx(a, maxofs, maxIdx);
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* norm *
|
||||
\****************************************************************************************/
|
||||
@ -1066,7 +1202,26 @@ double norm( const Mat& a, int normType )
|
||||
CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
|
||||
NormFunc func = tab[normType >> 1][a.depth()];
|
||||
CV_Assert(func != 0);
|
||||
double r = func(a);
|
||||
|
||||
double r = 0;
|
||||
if( a.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&a, 0};
|
||||
Mat planes[1];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
double n = func(it.planes[0]);
|
||||
if( normType == NORM_INF )
|
||||
r = std::max(r, n);
|
||||
else
|
||||
r += n;
|
||||
}
|
||||
}
|
||||
else
|
||||
r = func(a);
|
||||
|
||||
return normType == NORM_L2 ? std::sqrt(r) : r;
|
||||
}
|
||||
|
||||
@ -1111,10 +1266,32 @@ double norm( const Mat& a, int normType, const Mat& mask )
|
||||
|
||||
normType &= 7;
|
||||
CV_Assert((normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2) &&
|
||||
a.size() == mask.size() && mask.type() == CV_8U && a.channels() == 1);
|
||||
mask.type() == CV_8U && a.channels() == 1);
|
||||
NormMaskFunc func = tab[normType >> 1][a.depth()];
|
||||
CV_Assert(func != 0);
|
||||
double r = func(a, mask);
|
||||
|
||||
double r = 0;
|
||||
if( a.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&a, &mask, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
double n = func(it.planes[0], it.planes[1]);
|
||||
if( normType == NORM_INF )
|
||||
r = std::max(r, n);
|
||||
else
|
||||
r += n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert( a.size() == mask.size() );
|
||||
r = func(a, mask);
|
||||
}
|
||||
|
||||
return normType == NORM_L2 ? std::sqrt(r) : r;
|
||||
}
|
||||
|
||||
@ -1154,15 +1331,35 @@ double norm( const Mat& a, const Mat& b, int normType )
|
||||
}
|
||||
};
|
||||
|
||||
CV_Assert( a.type() == b.type() && a.size() == b.size() );
|
||||
|
||||
CV_Assert( a.type() == b.type() );
|
||||
bool isRelative = (normType & NORM_RELATIVE) != 0;
|
||||
normType &= 7;
|
||||
CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
|
||||
|
||||
NormDiffFunc func = tab[normType >> 1][a.depth()];
|
||||
CV_Assert(func != 0);
|
||||
double r = func( a, b );
|
||||
|
||||
double r = 0.;
|
||||
if( a.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&a, &b, 0};
|
||||
Mat planes[2];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
double n = func(it.planes[0], it.planes[1]);
|
||||
|
||||
if( normType == NORM_INF )
|
||||
r = std::max(r, n);
|
||||
else
|
||||
r += n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert( a.size() == b.size() );
|
||||
r = func( a, b );
|
||||
}
|
||||
if( normType == NORM_L2 )
|
||||
r = std::sqrt(r);
|
||||
if( isRelative )
|
||||
@ -1208,16 +1405,37 @@ double norm( const Mat& a, const Mat& b, int normType, const Mat& mask )
|
||||
if( !mask.data )
|
||||
return norm(a, b, normType);
|
||||
|
||||
CV_Assert( a.type() == b.type() && a.size() == b.size() &&
|
||||
a.size() == mask.size() && mask.type() == CV_8U && a.channels() == 1);
|
||||
|
||||
CV_Assert( a.type() == b.type() && mask.type() == CV_8U && a.channels() == 1);
|
||||
bool isRelative = (normType & NORM_RELATIVE) != 0;
|
||||
normType &= 7;
|
||||
CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
|
||||
|
||||
NormDiffMaskFunc func = tab[normType >> 1][a.depth()];
|
||||
CV_Assert(func != 0);
|
||||
double r = func( a, b, mask );
|
||||
|
||||
double r = 0.;
|
||||
if( a.dims > 2 )
|
||||
{
|
||||
const Mat* arrays[] = {&a, &b, &mask, 0};
|
||||
Mat planes[3];
|
||||
NAryMatIterator it(arrays, planes);
|
||||
|
||||
for( int i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
double n = func(it.planes[0], it.planes[1], it.planes[2]);
|
||||
|
||||
if( normType == NORM_INF )
|
||||
r = std::max(r, n);
|
||||
else
|
||||
r += n;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert( a.size() == b.size() && a.size() == mask.size() );
|
||||
r = func( a, b, mask );
|
||||
}
|
||||
|
||||
if( normType == NORM_L2 )
|
||||
r = std::sqrt(r);
|
||||
if( isRelative )
|
||||
|
Loading…
Reference in New Issue
Block a user