From 8af83e6d376fa73858561759bf4d4f39ba964027 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 19 Oct 2010 11:57:37 +0000 Subject: [PATCH] fixed a few bugs in: Mat::reshape, Mat(CvMat*) constructor, element access, copying nd array etc. --- modules/core/include/opencv2/core/core.hpp | 17 ++++++----- modules/core/include/opencv2/core/mat.hpp | 46 +++++++++++++++++++++++------- modules/core/src/array.cpp | 6 +++- modules/core/src/matrix.cpp | 36 ++++++++++++++++------- 4 files changed, 76 insertions(+), 29 deletions(-) diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 1d27cef..47b69f5 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -90,7 +90,6 @@ typedef Mat MatND; class CV_EXPORTS MatExpr; class CV_EXPORTS MatOp_Base; -class CV_EXPORTS VectorArg; class CV_EXPORTS MatArg; class CV_EXPORTS MatConstIterator; @@ -1257,11 +1256,11 @@ static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); } Custom array allocator */ -class CV_EXPORTS ArrayAllocator +class CV_EXPORTS MatAllocator { public: - ArrayAllocator() {} - virtual ~ArrayAllocator() {} + MatAllocator() {} + virtual ~MatAllocator() {} virtual void allocate(int dims, const int* sizes, int type, int*& refcount, uchar*& datastart, uchar*& data, size_t* step) = 0; virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0; @@ -1763,7 +1762,7 @@ public: uchar* datalimit; //! custom allocator - ArrayAllocator* allocator; + MatAllocator* allocator; struct CV_EXPORTS MSize { @@ -1797,7 +1796,7 @@ public: MStep step; }; - + /*! Random Number Generator @@ -1836,6 +1835,9 @@ public: uint64 state; }; + + + /*! Termination criteria in iterative algorithms @@ -2331,7 +2333,8 @@ public: //! converts elliptic arc to a polygonal curve CV_EXPORTS void ellipse2Poly( Point center, Size axes, int angle, - int arcStart, int arcEnd, int delta, CV_OUT vector& pts ); + int arcStart, int arcEnd, int delta, + CV_OUT vector& pts ); enum { diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index e53761f..a6bcbb5 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -172,8 +172,7 @@ inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step) inline Mat::Mat(const CvMat* m, bool copyData) : flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))), dims(2), rows(m->rows), cols(m->cols), data(m->data.ptr), refcount(0), - datastart(0), dataend(0), - allocator(0), size(&rows) + datastart(m->data.ptr), allocator(0), size(&rows) { if( !copyData ) { @@ -544,17 +543,41 @@ template inline const _Tp& Mat::at(Point pt) const } template inline _Tp& Mat::at(int i0) -{ return *(_Tp*)ptr(i0); } +{ + CV_DbgAssert( dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) && + (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) && + elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)(data + step.p[size.p[0]==1]*i0); +} + template inline const _Tp& Mat::at(int i0) const -{ return *(const _Tp*)ptr(i0); } +{ + CV_DbgAssert( dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) && + (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) && + elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)(data + step.p[size.p[0]==1]*i0); +} + template inline _Tp& Mat::at(int i0, int i1, int i2) -{ return *(_Tp*)ptr(i0, i1, i2); } +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)ptr(i0, i1, i2); +} template inline const _Tp& Mat::at(int i0, int i1, int i2) const -{ return *(const _Tp*)ptr(i0, i1, i2); } +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(const _Tp*)ptr(i0, i1, i2); +} template inline _Tp& Mat::at(const int* idx) -{ return *(_Tp*)ptr(idx); } +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)ptr(idx); +} template inline const _Tp& Mat::at(const int* idx) const -{ return *(const _Tp*)ptr(idx); } +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(const _Tp*)ptr(idx); +} template inline MatConstIterator_<_Tp> Mat::begin() const @@ -688,7 +711,9 @@ static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMod { return cvarrToMat(arr, copyData, true, coiMode); } - + +///////////////////////////////////////////// SVD ////////////////////////////////////////////////////// + inline SVD::SVD() {} inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); } inline void SVD::solveZ( const Mat& m, Mat& dst ) @@ -1015,6 +1040,7 @@ process( const Mat_& m1, const Mat_& m2, Mat_& m3, Op op ) } } +//////////////////////////////////// Matrix Expressions ///////////////////////////////////////// class CV_EXPORTS MatOp { @@ -1526,7 +1552,7 @@ template inline MatExpr Mat_<_Tp>::eye(Size sz) return Mat::eye(sz, DataType<_Tp>::type); } -//////////// Iterators & Comma initializers ////////////////// +//////////////////////////////// Iterators & Comma initializers ////////////////////////////////// inline MatConstIterator::MatConstIterator() : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {} diff --git a/modules/core/src/array.cpp b/modules/core/src/array.cpp index d78bfe2..be25e87 100644 --- a/modules/core/src/array.cpp +++ b/modules/core/src/array.cpp @@ -304,7 +304,11 @@ cvCloneMatND( const CvMatND* src ) if( src->data.ptr ) { cvCreateData( dst ); - cvCopy( src, dst ); + cv::Mat _src(src), _dst(dst); + uchar* data0 = dst->data.ptr; + _src.copyTo(_dst); + CV_Assert(_dst.data == data0); + //cvCopy( src, dst ); } return dst; diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 80113e9..63048ba 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -511,6 +511,10 @@ void Mat::reserve(size_t nelems) return; int r = size.p[0]; + + if( (size_t)r >= nelems ) + return; + size.p[0] = std::max((int)nelems, 1); size_t newsize = total()*elemSize(); @@ -534,6 +538,8 @@ void Mat::reserve(size_t nelems) void Mat::resize(size_t nelems) { int saveRows = size.p[0]; + if( saveRows == (int)nelems ) + return; CV_Assert( (int)nelems >= 0 ); if( isSubmatrix() || data + step.p[0]*nelems > datalimit ) @@ -725,12 +731,17 @@ Mat Mat::reshape(int new_cn, int new_rows) const hdr.cols = new_width; hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT); + hdr.step[1] = CV_ELEM_SIZE(hdr.flags); return hdr; } + +/*************************************************************************************************\ + Matrix Operations +\*************************************************************************************************/ -void -setIdentity( Mat& m, const Scalar& s ) +//////////////////////////////////////// set identity //////////////////////////////////////////// +void setIdentity( Mat& m, const Scalar& s ) { CV_Assert( m.dims <= 2 ); int i, j, rows = m.rows, cols = m.cols, type = m.type(); @@ -768,6 +779,8 @@ setIdentity( Mat& m, const Scalar& s ) } } +//////////////////////////////////////////// trace /////////////////////////////////////////// + Scalar trace( const Mat& m ) { CV_Assert( m.dims <= 2 ); @@ -797,10 +810,8 @@ Scalar trace( const Mat& m ) return cv::sum(m.diag()); } -/****************************************************************************************\ -* transpose * -\****************************************************************************************/ - +////////////////////////////////////// transpose ///////////////////////////////////////// + template static void transposeI_( Mat& mat ) { @@ -968,9 +979,7 @@ Mat Mat::cross(const Mat& m) const } -/****************************************************************************************\ -* Reduce Mat to vector * -\****************************************************************************************/ +////////////////////////////////////////// reduce //////////////////////////////////////////// template static void reduceR_( const Mat& srcmat, Mat& dstmat ) @@ -1178,6 +1187,8 @@ void reduce(const Mat& src, Mat& dst, int dim, int op, int dtype) temp.convertTo(dst, dst.type(), 1./(dim == 0 ? src.rows : src.cols)); } + +//////////////////////////////////////// sort /////////////////////////////////////////// template static void sort_( const Mat& src, Mat& dst, int flags ) { @@ -1307,6 +1318,10 @@ void sortIdx( const Mat& src, Mat& dst, int flags ) func( src, dst, flags ); } + + +////////////////////////////////////////// kmeans //////////////////////////////////////////// + static void generateRandomCenter(const vector& box, float* center, RNG& rng) { size_t j, dims = box.size(); @@ -2850,7 +2865,6 @@ void normalize( const SparseMat& src, SparseMat& dst, double a, int norm_type ) src.convertTo( dst, -1, scale ); } - } - + /* End of file. */ -- 2.7.4