united cv::Mat and cv::MatND

This commit is contained in:
Vadim Pisarevsky 2010-10-12 12:31:40 +00:00
parent f6895e7738
commit 541441e85b
13 changed files with 2428 additions and 2759 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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 );
}

View File

@ -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 );
func( src, mv );
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 );
func( mv, dst );
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);
}
}
}

View File

@ -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,7 +294,18 @@ Mat& Mat::setTo(const Scalar& s, const Mat& mask)
CV_Assert( func != 0 );
double buf[4];
scalarToRawData(s, buf, type(), 0);
func(buf, *this, mask);
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();

View File

@ -347,7 +347,19 @@ static CvStatus CV_STDCALL Sqrt_64f(const double* src, double* dst, int len)
void magnitude( const Mat& X, const Mat& Y, Mat& Mag )
{
int type = X.type(), depth = X.depth(), cn = X.channels();
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;

View File

@ -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

View File

@ -5266,14 +5266,16 @@ void writeScalar(FileStorage& fs, const string& value )
void write( FileStorage& fs, const string& name, const Mat& value )
{
CvMat mat = value;
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
}
void write( FileStorage& fs, const string& name, const MatND& value )
{
CvMatND mat = value;
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
if( value.dims <= 2 )
{
CvMat mat = value;
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
}
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 )

View File

@ -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 );
for( int i = 0; i < it.nplanes; i++, ++it )
func( it.planes[0], &state, param );
}
else
func( mat, &state, param );
}
#ifdef WIN32

View File

@ -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()];
MeanStdDevMaskFunc mfunc = mtab[m.type()];
CV_Assert( func != 0 || mfunc != 0 );
if( m.dims > 2 )
{
MeanStdDevFunc func = tab[m.type()];
CV_Assert( func != 0 );
func( m, mean, stddev );
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 )