diff --git a/modules/core/include/opencv2/core/cvstd.inl.hpp b/modules/core/include/opencv2/core/cvstd.inl.hpp index 2a5b170f90..874364e3c1 100644 --- a/modules/core/include/opencv2/core/cvstd.inl.hpp +++ b/modules/core/include/opencv2/core/cvstd.inl.hpp @@ -270,6 +270,17 @@ std::ostream& operator << (std::ostream& out, const Rect_<_Tp>& rect) return out << "[" << rect.width << " x " << rect.height << " from (" << rect.x << ", " << rect.y << ")]"; } +static inline std::ostream& operator << (std::ostream& out, const MatSize& msize) +{ + int i, dims = msize.p[-1]; + for( i = 0; i < dims; i++ ) + { + out << msize.p[i]; + if( i < dims-1 ) + out << " x "; + } + return out; +} #endif // OPENCV_NOSTL } // cv diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index d8adaeed04..cb77ed4edc 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -1243,6 +1243,9 @@ public: /** @overload */ Mat reshape(int cn, int newndims, const int* newsz) const; + /** @overload */ + Mat reshape(int cn, const std::vector& newshape) const; + /** @brief Transposes a matrix. The method performs matrix transposition by means of matrix expressions. It does not perform the @@ -1749,6 +1752,12 @@ public: */ size_t total() const; + /** @brief Returns the total number of array elements. + + The method returns the number of elements within a certain sub-array slice with startDim <= dim < endDim + */ + size_t total(int startDim, int endDim=INT_MAX) const; + //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 399c92220d..72bc915abf 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -878,6 +878,17 @@ size_t Mat::total() const return p; } +inline +size_t Mat::total(int startDim, int endDim) const +{ + CV_Assert( 0 <= startDim && startDim <= endDim); + size_t p = 1; + int endDim_ = endDim <= dims ? endDim : dims; + for( int i = startDim; i < endDim_; i++ ) + p *= size[i]; + return p; +} + inline uchar* Mat::ptr(int y) { diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 7dd951a225..8a4199ff83 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -1052,12 +1052,20 @@ Mat Mat::reshape(int new_cn, int new_rows) const int cn = channels(); Mat hdr = *this; - if( dims > 2 && new_rows == 0 && new_cn != 0 && size[dims-1]*cn % new_cn == 0 ) + if( dims > 2 ) { - hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT); - hdr.step[dims-1] = CV_ELEM_SIZE(hdr.flags); - hdr.size[dims-1] = hdr.size[dims-1]*cn / new_cn; - return hdr; + if( new_rows == 0 && new_cn != 0 && size[dims-1]*cn % new_cn == 0 ) + { + hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT); + hdr.step[dims-1] = CV_ELEM_SIZE(hdr.flags); + hdr.size[dims-1] = hdr.size[dims-1]*cn / new_cn; + return hdr; + } + if( new_rows > 0 ) + { + int sz[] = { new_rows, (int)(total()/new_rows) }; + return reshape(new_cn, 2, sz); + } } CV_Assert( dims <= 2 ); @@ -4706,6 +4714,18 @@ Mat Mat::reshape(int _cn, int _newndims, const int* _newsz) const return Mat(); } +Mat Mat::reshape(int _cn, const std::vector& _newshape) const +{ + if(_newshape.empty()) + { + CV_Assert(empty()); + return *this; + } + + return reshape(_cn, (int)_newshape.size(), &_newshape[0]); +} + + NAryMatIterator::NAryMatIterator() : arrays(0), planes(0), ptrs(0), narrays(0), nplanes(0), size(0), iterdepth(0), idx(0) {