Commit 541441e8 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

united cv::Mat and cv::MatND

parent f6895e77
This diff is collapsed.
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
......@@ -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 );
......
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment