diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index a2bb752de9..de786da1ba 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -1305,6 +1305,7 @@ public: template<typename _Tp> _InputArray(const vector<_Tp>& vec); template<typename _Tp> _InputArray(const vector<vector<_Tp> >& vec); _InputArray(const vector<Mat>& vec); + template<typename _Tp> _InputArray(const vector<Mat_<_Tp> >& vec); template<typename _Tp> _InputArray(const Mat_<_Tp>& m); template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx); _InputArray(const Scalar& s); @@ -1360,6 +1361,7 @@ public: template<typename _Tp> _OutputArray(vector<_Tp>& vec); template<typename _Tp> _OutputArray(vector<vector<_Tp> >& vec); _OutputArray(vector<Mat>& vec); + template<typename _Tp> _OutputArray(vector<Mat_<_Tp> >& vec); template<typename _Tp> _OutputArray(Mat_<_Tp>& m); template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx); template<typename _Tp> _OutputArray(_Tp* vec, int n); @@ -1368,6 +1370,7 @@ public: template<typename _Tp> _OutputArray(const vector<_Tp>& vec); template<typename _Tp> _OutputArray(const vector<vector<_Tp> >& vec); _OutputArray(const vector<Mat>& vec); + template<typename _Tp> _OutputArray(const vector<Mat_<_Tp> >& vec); template<typename _Tp> _OutputArray(const Mat_<_Tp>& m); template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx); template<typename _Tp> _OutputArray(const _Tp* vec, int n); @@ -2112,12 +2115,12 @@ CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, in //! makes multi-channel array out of several single-channel arrays CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst); //! makes multi-channel array out of several single-channel arrays -CV_EXPORTS_W void merge(const vector<Mat>& mv, OutputArray dst); +CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst); //! copies each plane of a multi-channel array to a dedicated array CV_EXPORTS void split(const Mat& src, Mat* mvbegin); //! copies each plane of a multi-channel array to a dedicated array -CV_EXPORTS_W void split(const Mat& m, CV_OUT vector<Mat>& mv); +CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv); //! copies selected channels from the input arrays to the selected channels of the output arrays CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index d9ab8d7775..29234b073d 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -1118,6 +1118,9 @@ template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec) template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp> >& vec) : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {} +template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec) + : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {} + template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx) : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {} @@ -1130,18 +1133,32 @@ inline _InputArray::_InputArray(const Scalar& s) template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m) : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {} -template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec) : _InputArray(vec) {} -template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec) : _InputArray(vec) {} -template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m) : _InputArray(m) {} -template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) : _InputArray(mtx) {} -template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n) : _InputArray(vec, n) {} - - -template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec) : _InputArray(vec) {flags |= FIXED_SIZE;} -template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec) : _InputArray(vec) {flags |= FIXED_SIZE;} -template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m) : _InputArray(m) {flags |= FIXED_SIZE;} -template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx) : _InputArray(mtx) {} -template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n) : _InputArray(vec, n) {} +template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec) + : _InputArray(vec) {} +template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec) + : _InputArray(vec) {} +template<typename _Tp> inline _OutputArray::_OutputArray(vector<Mat_<_Tp> >& vec) + : _InputArray(vec) {} +template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m) + : _InputArray(m) {} +template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) + : _InputArray(mtx) {} +template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n) + : _InputArray(vec, n) {} + +template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec) + : _InputArray(vec) {flags |= FIXED_SIZE;} +template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec) + : _InputArray(vec) {flags |= FIXED_SIZE;} +template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec) + : _InputArray(vec) {flags |= FIXED_SIZE;} + +template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m) + : _InputArray(m) {flags |= FIXED_SIZE;} +template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx) + : _InputArray(mtx) {} +template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n) + : _InputArray(vec, n) {} //////////////////////////////////// Matrix Expressions ///////////////////////////////////////// diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index 043b5aa872..523555f4b1 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -253,11 +253,18 @@ void cv::split(const Mat& src, Mat* mv) } } -void cv::split(const Mat& m, vector<Mat>& mv) +void cv::split(InputArray _m, OutputArrayOfArrays _mv) { - mv.resize(!m.empty() ? m.channels() : 0); - if(!m.empty()) - split(m, &mv[0]); + Mat m = _m.getMat(); + if( m.empty() ) + { + _mv.release(); + return; + } + CV_Assert( !_mv.fixedType() || CV_MAT_TYPE(_mv.flags) == m.depth() ); + _mv.create(m.channels(), 1, m.depth()); + Mat* dst = &_mv.getMatRef(0); + split(m, dst); } void cv::merge(const Mat* mv, size_t n, OutputArray _dst) @@ -335,8 +342,10 @@ void cv::merge(const Mat* mv, size_t n, OutputArray _dst) } } -void cv::merge(const vector<Mat>& mv, OutputArray _dst) +void cv::merge(InputArrayOfArrays _mv, OutputArray _dst) { + vector<Mat> mv; + _mv.getMatVector(mv); merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst); } diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 89d2bbfd45..670388d74f 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -1470,10 +1470,21 @@ void _OutputArray::create(int dims, const int* size, int type, int i, bool allow if( i < 0 ) { CV_Assert( dims == 2 && (size[0] == 1 || size[1] == 1 || size[0]*size[1] == 0) ); - size_t len = size[0]*size[1] > 0 ? size[0] + size[1] - 1 : 0; + size_t len = size[0]*size[1] > 0 ? size[0] + size[1] - 1 : 0, len0 = v.size(); - CV_Assert(!fixedSize() || len == v.size()); + CV_Assert(!fixedSize() || len == len0); v.resize(len); + if( fixedType() ) + { + int type = CV_MAT_TYPE(flags); + for( size_t j = len0; j < len; j++ ) + { + if( v[i].type() == type ) + continue; + CV_Assert( v[i].empty() ); + v[i].flags = (v[i].flags & ~CV_MAT_TYPE_MASK) | type; + } + } return; } diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index 1069c8d7bb..62dbc9d649 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -749,7 +749,15 @@ bool CV_OperationsTest::TestTemplateMat() if (Mat3i(1, 1).channels() != 3) throw test_excep(); if (Mat3w(1, 1).channels() != 3) throw test_excep(); if (Mat3s(1, 1).channels() != 3) throw test_excep(); - + + vector<Mat_<float> > mvf, mvf2; + Mat_<Vec2f> mf2; + mvf.push_back(Mat_<float>::ones(4, 3)); + mvf.push_back(Mat_<float>::zeros(4, 3)); + merge(mvf, mf2); + split(mf2, mvf2); + CV_Assert( norm(mvf2[0], mvf[0], CV_C) == 0 && + norm(mvf2[1], mvf[1], CV_C) == 0 ); } catch (const test_excep& e) {