diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index 25ab93dfa..37741c399 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -289,10 +289,12 @@ static bool ocl_split( InputArray _m, OutputArrayOfArrays _mv ) return false; Size size = _m.size(); - std::vector & dst = *(std::vector *)_mv.getObj(); - dst.resize(cn); + _mv.create(cn, 1, depth); for (int i = 0; i < cn; ++i) - dst[i].create(size, depth); + _mv.create(size, depth, i); + + std::vector dst; + _mv.getUMatVector(dst); int argidx = k.set(0, ocl::KernelArg::ReadOnly(_m.getUMat())); for (int i = 0; i < cn; ++i) @@ -317,10 +319,19 @@ void cv::split(InputArray _m, OutputArrayOfArrays _mv) _mv.release(); return; } + CV_Assert( !_mv.fixedType() || _mv.empty() || _mv.type() == m.depth() ); - _mv.create(m.channels(), 1, m.depth()); - Mat* dst = &_mv.getMatRef(0); - split(m, dst); + + Size size = m.size(); + int depth = m.depth(), cn = m.channels(); + _mv.create(cn, 1, depth); + for (int i = 0; i < cn; ++i) + _mv.create(size, depth, i); + + std::vector dst; + _mv.getMatVector(dst); + + split(m, &dst[0]); } void cv::merge(const Mat* mv, size_t n, OutputArray _dst) @@ -404,7 +415,8 @@ namespace cv { static bool ocl_merge( InputArrayOfArrays _mv, OutputArray _dst ) { - const std::vector & src = *(const std::vector *)(_mv.getObj()); + std::vector src; + _mv.getUMatVector(src); CV_Assert(!src.empty()); int type = src[0].type(), depth = CV_MAT_DEPTH(type); @@ -651,8 +663,9 @@ static void getUMatIndex(const std::vector & um, int cn, int & idx, int & static bool ocl_mixChannels(InputArrayOfArrays _src, InputOutputArrayOfArrays _dst, const int* fromTo, size_t npairs) { - const std::vector & src = *(const std::vector *)_src.getObj(); - std::vector & dst = *(std::vector *)_dst.getObj(); + std::vector src, dst; + _src.getUMatVector(src); + _dst.getUMatVector(dst); size_t nsrc = src.size(), ndst = dst.size(); CV_Assert(nsrc > 0 && ndst > 0); @@ -718,7 +731,7 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst, if (npairs == 0 || fromTo == NULL) return; - CV_OCL_RUN(src.isUMatVector() && dst.isUMatVector(), + CV_OCL_RUN(dst.isUMatVector(), ocl_mixChannels(src, dst, fromTo, npairs)) bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT && @@ -747,7 +760,7 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst, if (fromTo.empty()) return; - CV_OCL_RUN(src.isUMatVector() && dst.isUMatVector(), + CV_OCL_RUN(dst.isUMatVector(), ocl_mixChannels(src, dst, &fromTo[0], fromTo.size()>>1)) bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT && diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 338fe6844..c74e854f1 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -1193,7 +1193,6 @@ Mat _InputArray::getMat(int i) const return Mat(); } - UMat _InputArray::getUMat(int i) const { int k = kind(); @@ -1226,7 +1225,6 @@ UMat _InputArray::getUMat(int i) const return getMat(i).getUMat(accessFlags); } - void _InputArray::getMatVector(std::vector& mv) const { int k = kind(); @@ -1504,7 +1502,6 @@ Size _InputArray::size(int i) const } } - int _InputArray::sizend(int* arrsz, int i) const { int j, d=0, k = kind(); @@ -1563,7 +1560,6 @@ int _InputArray::sizend(int* arrsz, int i) const return d; } - bool _InputArray::sameSize(const _InputArray& arr) const { int k1 = kind(), k2 = arr.kind(); @@ -2305,7 +2301,66 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 ) mtype = m.type(); else - CV_Assert(!fixedType() || (CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0)); + CV_Assert(CV_MAT_TYPE(mtype) == m.type()); + } + if(fixedSize()) + { + CV_Assert(m.dims == d); + for(int j = 0; j < d; ++j) + CV_Assert(m.size[j] == sizes[j]); + } + + m.create(d, sizes, mtype); + return; + } + + if( k == STD_VECTOR_UMAT ) + { + std::vector& v = *(std::vector*)obj; + + if( i < 0 ) + { + CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) ); + size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = 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[j].type() == _type ) + continue; + CV_Assert( v[j].empty() ); + v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type; + } + } + return; + } + + CV_Assert( i < (int)v.size() ); + UMat& m = v[i]; + + if( allowTransposed ) + { + if( !m.isContinuous() ) + { + CV_Assert(!fixedType() && !fixedSize()); + m.release(); + } + + if( d == 2 && m.dims == 2 && m.u && + m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] ) + return; + } + + if(fixedType()) + { + if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 ) + mtype = m.type(); + else + CV_Assert(CV_MAT_TYPE(mtype) == m.type()); } if(fixedSize()) { diff --git a/modules/core/test/ocl/test_channels.cpp b/modules/core/test/ocl/test_channels.cpp index 09d709e91..f0dc10250 100644 --- a/modules/core/test/ocl/test_channels.cpp +++ b/modules/core/test/ocl/test_channels.cpp @@ -197,7 +197,7 @@ PARAM_TEST_CASE(Split, MatType, Channels, bool) } }; -OCL_TEST_P(Split, DISABLED_Accuracy) +OCL_TEST_P(Split, Accuracy) { for (int j = 0; j < test_loop_times; j++) {