united cv::Mat and cv::MatND

pull/13383/head
Vadim Pisarevsky 15 years ago
parent f6895e7738
commit 541441e85b
  1. 1079
      modules/core/include/opencv2/core/core.hpp
  2. 1611
      modules/core/include/opencv2/core/mat.hpp
  3. 1
      modules/core/include/opencv2/core/operations.hpp
  4. 5
      modules/core/include/opencv2/core/types_c.h
  5. 286
      modules/core/src/arithm.cpp
  6. 111
      modules/core/src/convert.cpp
  7. 56
      modules/core/src/copy.cpp
  8. 109
      modules/core/src/mathfuncs.cpp
  9. 14
      modules/core/src/matmul.cpp
  10. 1641
      modules/core/src/matrix.cpp
  11. 47
      modules/core/src/persistence.cpp
  12. 23
      modules/core/src/rand.cpp
  13. 272
      modules/core/src/stat.cpp

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 );
}
@ -1223,6 +1404,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 );
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;
int i, total = 0, n = (int)_n;
Size size = mv[0].size();
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,22 +743,46 @@ 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);
}
}
}
/****************************************************************************************\

@ -168,7 +168,22 @@ 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;
@ -192,6 +207,18 @@ void Mat::copyTo( Mat& dst, const Mat& mask ) const
copyTo(dst);
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() );
@ -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();

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

@ -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,16 +5266,18 @@ 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 );
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 );
}
}
void write( FileStorage& fs, const string& name, const MatND& value )
{
CvMatND mat = value;
cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
}
// TODO: the 4 functions below need to be implemented more efficiently
void write( FileStorage& fs, const string& name, const SparseMat& value )
{
@ -5301,23 +5303,24 @@ 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 )
{
if( node.empty() )

@ -482,7 +482,7 @@ void RNG::fill( Mat& mat, int disttype, const Scalar& param1, const Scalar& para
Randn_<float,float>,
Randn_<double,double>, 0}
};
int depth = mat.depth(), channels = mat.channels();
double dparam[2][12];
float fparam[2][12];
@ -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);
for( int i = 0; i < it.nplanes; i++, ++it )
fill( it.planes[0], disttype, param1, param2 );
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 )
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()];
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;
}
else
if( mask.data )
{
MeanStdDevMaskFunc func = mtab[m.type()];
CV_Assert( mask.size() == m.size() && mask.type() == CV_8U && func != 0 );
func( m, mask, mean, stddev );
CV_Assert( mask.size() == m.size() );
mfunc( m, mask, mean, stddev );
}
else
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…
Cancel
Save