// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html #include "opencv2/core/mat.hpp" #include "precomp.hpp" namespace cv { /*************************************************************************************************\ Input/Output Array \*************************************************************************************************/ Mat _InputArray::getMat_(int i) const { int k = kind(); int accessFlags = flags & ACCESS_MASK; if( k == MAT ) { const Mat* m = (const Mat*)obj; if( i < 0 ) return *m; return m->row(i); } if( k == UMAT ) { const UMat* m = (const UMat*)obj; if( i < 0 ) return m->getMat(accessFlags); return m->getMat(accessFlags).row(i); } if( k == EXPR ) { CV_Assert( i < 0 ); return (Mat)*((const MatExpr*)obj); } if( k == MATX || k == STD_ARRAY ) { CV_Assert( i < 0 ); return Mat(sz, flags, obj); } if( k == STD_VECTOR ) { CV_Assert( i < 0 ); int t = CV_MAT_TYPE(flags); const std::vector& v = *(const std::vector*)obj; return !v.empty() ? Mat(size(), t, (void*)&v[0]) : Mat(); } if( k == STD_BOOL_VECTOR ) { CV_Assert( i < 0 ); int t = CV_8U; const std::vector& v = *(const std::vector*)obj; int j, n = (int)v.size(); if( n == 0 ) return Mat(); Mat m(1, n, t); uchar* dst = m.data; for( j = 0; j < n; j++ ) dst[j] = (uchar)v[j]; return m; } if( k == NONE ) return Mat(); if( k == STD_VECTOR_VECTOR ) { int t = type(i); const std::vector >& vv = *(const std::vector >*)obj; CV_Assert( 0 <= i && i < (int)vv.size() ); const std::vector& v = vv[i]; return !v.empty() ? Mat(size(i), t, (void*)&v[0]) : Mat(); } if( k == STD_VECTOR_MAT ) { const std::vector& v = *(const std::vector*)obj; CV_Assert( 0 <= i && i < (int)v.size() ); return v[i]; } if( k == STD_ARRAY_MAT ) { const Mat* v = (const Mat*)obj; CV_Assert( 0 <= i && i < sz.height ); return v[i]; } if( k == STD_VECTOR_UMAT ) { const std::vector& v = *(const std::vector*)obj; CV_Assert( 0 <= i && i < (int)v.size() ); return v[i].getMat(accessFlags); } if( k == OPENGL_BUFFER ) { CV_Assert( i < 0 ); CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapHost/unmapHost methods for ogl::Buffer object"); return Mat(); } if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); CV_Error(cv::Error::StsNotImplemented, "You should explicitly call download method for cuda::GpuMat object"); return Mat(); } if( k == CUDA_HOST_MEM ) { CV_Assert( i < 0 ); const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj; return cuda_mem->createMatHeader(); } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); return Mat(); } UMat _InputArray::getUMat(int i) const { int k = kind(); int accessFlags = flags & ACCESS_MASK; if( k == UMAT ) { const UMat* m = (const UMat*)obj; if( i < 0 ) return *m; return m->row(i); } if( k == STD_VECTOR_UMAT ) { const std::vector& v = *(const std::vector*)obj; CV_Assert( 0 <= i && i < (int)v.size() ); return v[i]; } if( k == MAT ) { const Mat* m = (const Mat*)obj; if( i < 0 ) return m->getUMat(accessFlags); return m->row(i).getUMat(accessFlags); } return getMat(i).getUMat(accessFlags); } void _InputArray::getMatVector(std::vector& mv) const { int k = kind(); int accessFlags = flags & ACCESS_MASK; if( k == MAT ) { const Mat& m = *(const Mat*)obj; int n = (int)m.size[0]; mv.resize(n); for( int i = 0; i < n; i++ ) mv[i] = m.dims == 2 ? Mat(1, m.cols, m.type(), (void*)m.ptr(i)) : Mat(m.dims-1, &m.size[1], m.type(), (void*)m.ptr(i), &m.step[1]); return; } if( k == EXPR ) { Mat m = *(const MatExpr*)obj; int n = m.size[0]; mv.resize(n); for( int i = 0; i < n; i++ ) mv[i] = m.row(i); return; } if( k == MATX || k == STD_ARRAY ) { size_t n = sz.height, esz = CV_ELEM_SIZE(flags); mv.resize(n); for( size_t i = 0; i < n; i++ ) mv[i] = Mat(1, sz.width, CV_MAT_TYPE(flags), (uchar*)obj + esz*sz.width*i); return; } if( k == STD_VECTOR ) { const std::vector& v = *(const std::vector*)obj; size_t n = size().width, esz = CV_ELEM_SIZE(flags); int t = CV_MAT_DEPTH(flags), cn = CV_MAT_CN(flags); mv.resize(n); for( size_t i = 0; i < n; i++ ) mv[i] = Mat(1, cn, t, (void*)(&v[0] + esz*i)); return; } if( k == NONE ) { mv.clear(); return; } if( k == STD_VECTOR_VECTOR ) { const std::vector >& vv = *(const std::vector >*)obj; int n = (int)vv.size(); int t = CV_MAT_TYPE(flags); mv.resize(n); for( int i = 0; i < n; i++ ) { const std::vector& v = vv[i]; mv[i] = Mat(size(i), t, (void*)&v[0]); } return; } if( k == STD_VECTOR_MAT ) { const std::vector& v = *(const std::vector*)obj; size_t n = v.size(); mv.resize(n); for( size_t i = 0; i < n; i++ ) mv[i] = v[i]; return; } if( k == STD_ARRAY_MAT ) { const Mat* v = (const Mat*)obj; size_t n = sz.height; mv.resize(n); for( size_t i = 0; i < n; i++ ) mv[i] = v[i]; return; } if( k == STD_VECTOR_UMAT ) { const std::vector& v = *(const std::vector*)obj; size_t n = v.size(); mv.resize(n); for( size_t i = 0; i < n; i++ ) mv[i] = v[i].getMat(accessFlags); return; } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } void _InputArray::getUMatVector(std::vector& umv) const { int k = kind(); int accessFlags = flags & ACCESS_MASK; if( k == NONE ) { umv.clear(); return; } if( k == STD_VECTOR_MAT ) { const std::vector& v = *(const std::vector*)obj; size_t n = v.size(); umv.resize(n); for( size_t i = 0; i < n; i++ ) umv[i] = v[i].getUMat(accessFlags); return; } if( k == STD_ARRAY_MAT ) { const Mat* v = (const Mat*)obj; size_t n = sz.height; umv.resize(n); for( size_t i = 0; i < n; i++ ) umv[i] = v[i].getUMat(accessFlags); return; } if( k == STD_VECTOR_UMAT ) { const std::vector& v = *(const std::vector*)obj; size_t n = v.size(); umv.resize(n); for( size_t i = 0; i < n; i++ ) umv[i] = v[i]; return; } if( k == UMAT ) { UMat& v = *(UMat*)obj; umv.resize(1); umv[0] = v; return; } if( k == MAT ) { Mat& v = *(Mat*)obj; umv.resize(1); umv[0] = v.getUMat(accessFlags); return; } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } cuda::GpuMat _InputArray::getGpuMat() const { int k = kind(); if (k == CUDA_GPU_MAT) { const cuda::GpuMat* d_mat = (const cuda::GpuMat*)obj; return *d_mat; } if (k == CUDA_HOST_MEM) { const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj; return cuda_mem->createGpuMatHeader(); } if (k == OPENGL_BUFFER) { CV_Error(cv::Error::StsNotImplemented, "You should explicitly call mapDevice/unmapDevice methods for ogl::Buffer object"); return cuda::GpuMat(); } if (k == NONE) return cuda::GpuMat(); CV_Error(cv::Error::StsNotImplemented, "getGpuMat is available only for cuda::GpuMat and cuda::HostMem"); return cuda::GpuMat(); } void _InputArray::getGpuMatVector(std::vector& gpumv) const { int k = kind(); if (k == STD_VECTOR_CUDA_GPU_MAT) { gpumv = *(std::vector*)obj; } } ogl::Buffer _InputArray::getOGlBuffer() const { int k = kind(); CV_Assert(k == OPENGL_BUFFER); const ogl::Buffer* gl_buf = (const ogl::Buffer*)obj; return *gl_buf; } int _InputArray::kind() const { return flags & KIND_MASK; } int _InputArray::rows(int i) const { return size(i).height; } int _InputArray::cols(int i) const { return size(i).width; } Size _InputArray::size(int i) const { int k = kind(); if( k == MAT ) { CV_Assert( i < 0 ); return ((const Mat*)obj)->size(); } if( k == EXPR ) { CV_Assert( i < 0 ); return ((const MatExpr*)obj)->size(); } if( k == UMAT ) { CV_Assert( i < 0 ); return ((const UMat*)obj)->size(); } if( k == MATX || k == STD_ARRAY ) { CV_Assert( i < 0 ); return sz; } if( k == STD_VECTOR ) { CV_Assert( i < 0 ); const std::vector& v = *(const std::vector*)obj; const std::vector& iv = *(const std::vector*)obj; size_t szb = v.size(), szi = iv.size(); return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1); } if( k == STD_BOOL_VECTOR ) { CV_Assert( i < 0 ); const std::vector& v = *(const std::vector*)obj; return Size((int)v.size(), 1); } if( k == NONE ) return Size(); if( k == STD_VECTOR_VECTOR ) { const std::vector >& vv = *(const std::vector >*)obj; if( i < 0 ) return vv.empty() ? Size() : Size((int)vv.size(), 1); CV_Assert( i < (int)vv.size() ); const std::vector >& ivv = *(const std::vector >*)obj; size_t szb = vv[i].size(), szi = ivv[i].size(); return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1); } if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return vv.empty() ? Size() : Size((int)vv.size(), 1); CV_Assert( i < (int)vv.size() ); return vv[i].size(); } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; if( i < 0 ) return sz.height==0 ? Size() : Size(sz.height, 1); CV_Assert( i < sz.height ); return vv[i].size(); } if (k == STD_VECTOR_CUDA_GPU_MAT) { const std::vector& vv = *(const std::vector*)obj; if (i < 0) return vv.empty() ? Size() : Size((int)vv.size(), 1); CV_Assert(i < (int)vv.size()); return vv[i].size(); } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return vv.empty() ? Size() : Size((int)vv.size(), 1); CV_Assert( i < (int)vv.size() ); return vv[i].size(); } if( k == OPENGL_BUFFER ) { CV_Assert( i < 0 ); const ogl::Buffer* buf = (const ogl::Buffer*)obj; return buf->size(); } if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); const cuda::GpuMat* d_mat = (const cuda::GpuMat*)obj; return d_mat->size(); } if( k == CUDA_HOST_MEM ) { CV_Assert( i < 0 ); const cuda::HostMem* cuda_mem = (const cuda::HostMem*)obj; return cuda_mem->size(); } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); return Size(); } int _InputArray::sizend(int* arrsz, int i) const { int j, d=0, k = kind(); if( k == NONE ) ; else if( k == MAT ) { CV_Assert( i < 0 ); const Mat& m = *(const Mat*)obj; d = m.dims; if(arrsz) for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } else if( k == UMAT ) { CV_Assert( i < 0 ); const UMat& m = *(const UMat*)obj; d = m.dims; if(arrsz) for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } else if( k == STD_VECTOR_MAT && i >= 0 ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert( i < (int)vv.size() ); const Mat& m = vv[i]; d = m.dims; if(arrsz) for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } else if( k == STD_ARRAY_MAT && i >= 0 ) { const Mat* vv = (const Mat*)obj; CV_Assert( i < sz.height ); const Mat& m = vv[i]; d = m.dims; if(arrsz) for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } else if( k == STD_VECTOR_UMAT && i >= 0 ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert( i < (int)vv.size() ); const UMat& m = vv[i]; d = m.dims; if(arrsz) for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } else { Size sz2d = size(i); d = 2; if(arrsz) { arrsz[0] = sz2d.height; arrsz[1] = sz2d.width; } } return d; } bool _InputArray::sameSize(const _InputArray& arr) const { int k1 = kind(), k2 = arr.kind(); Size sz1; if( k1 == MAT ) { const Mat* m = ((const Mat*)obj); if( k2 == MAT ) return m->size == ((const Mat*)arr.obj)->size; if( k2 == UMAT ) return m->size == ((const UMat*)arr.obj)->size; if( m->dims > 2 ) return false; sz1 = m->size(); } else if( k1 == UMAT ) { const UMat* m = ((const UMat*)obj); if( k2 == MAT ) return m->size == ((const Mat*)arr.obj)->size; if( k2 == UMAT ) return m->size == ((const UMat*)arr.obj)->size; if( m->dims > 2 ) return false; sz1 = m->size(); } else sz1 = size(); if( arr.dims() > 2 ) return false; return sz1 == arr.size(); } int _InputArray::dims(int i) const { int k = kind(); if( k == MAT ) { CV_Assert( i < 0 ); return ((const Mat*)obj)->dims; } if( k == EXPR ) { CV_Assert( i < 0 ); return ((const MatExpr*)obj)->a.dims; } if( k == UMAT ) { CV_Assert( i < 0 ); return ((const UMat*)obj)->dims; } if( k == MATX || k == STD_ARRAY ) { CV_Assert( i < 0 ); return 2; } if( k == STD_VECTOR || k == STD_BOOL_VECTOR ) { CV_Assert( i < 0 ); return 2; } if( k == NONE ) return 0; if( k == STD_VECTOR_VECTOR ) { const std::vector >& vv = *(const std::vector >*)obj; if( i < 0 ) return 1; CV_Assert( i < (int)vv.size() ); return 2; } if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return 1; CV_Assert( i < (int)vv.size() ); return vv[i].dims; } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; if( i < 0 ) return 1; CV_Assert( i < sz.height ); return vv[i].dims; } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return 1; CV_Assert( i < (int)vv.size() ); return vv[i].dims; } if( k == OPENGL_BUFFER ) { CV_Assert( i < 0 ); return 2; } if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); return 2; } if( k == CUDA_HOST_MEM ) { CV_Assert( i < 0 ); return 2; } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); return 0; } size_t _InputArray::total(int i) const { int k = kind(); if( k == MAT ) { CV_Assert( i < 0 ); return ((const Mat*)obj)->total(); } if( k == UMAT ) { CV_Assert( i < 0 ); return ((const UMat*)obj)->total(); } if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return vv.size(); CV_Assert( i < (int)vv.size() ); return vv[i].total(); } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; if( i < 0 ) return sz.height; CV_Assert( i < sz.height ); return vv[i].total(); } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return vv.size(); CV_Assert( i < (int)vv.size() ); return vv[i].total(); } return size(i).area(); } int _InputArray::type(int i) const { int k = kind(); if( k == MAT ) return ((const Mat*)obj)->type(); if( k == UMAT ) return ((const UMat*)obj)->type(); if( k == EXPR ) return ((const MatExpr*)obj)->type(); if( k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return CV_MAT_TYPE(flags); if( k == NONE ) return -1; if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; if( vv.empty() ) { CV_Assert((flags & FIXED_TYPE) != 0); return CV_MAT_TYPE(flags); } CV_Assert( i < (int)vv.size() ); return vv[i >= 0 ? i : 0].type(); } if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; if( vv.empty() ) { CV_Assert((flags & FIXED_TYPE) != 0); return CV_MAT_TYPE(flags); } CV_Assert( i < (int)vv.size() ); return vv[i >= 0 ? i : 0].type(); } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; if( sz.height == 0 ) { CV_Assert((flags & FIXED_TYPE) != 0); return CV_MAT_TYPE(flags); } CV_Assert( i < sz.height ); return vv[i >= 0 ? i : 0].type(); } if (k == STD_VECTOR_CUDA_GPU_MAT) { const std::vector& vv = *(const std::vector*)obj; if (vv.empty()) { CV_Assert((flags & FIXED_TYPE) != 0); return CV_MAT_TYPE(flags); } CV_Assert(i < (int)vv.size()); return vv[i >= 0 ? i : 0].type(); } if( k == OPENGL_BUFFER ) return ((const ogl::Buffer*)obj)->type(); if( k == CUDA_GPU_MAT ) return ((const cuda::GpuMat*)obj)->type(); if( k == CUDA_HOST_MEM ) return ((const cuda::HostMem*)obj)->type(); CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); return 0; } int _InputArray::depth(int i) const { return CV_MAT_DEPTH(type(i)); } int _InputArray::channels(int i) const { return CV_MAT_CN(type(i)); } bool _InputArray::empty() const { int k = kind(); if( k == MAT ) return ((const Mat*)obj)->empty(); if( k == UMAT ) return ((const UMat*)obj)->empty(); if( k == EXPR ) return false; if( k == MATX || k == STD_ARRAY ) return false; if( k == STD_VECTOR ) { const std::vector& v = *(const std::vector*)obj; return v.empty(); } if( k == STD_BOOL_VECTOR ) { const std::vector& v = *(const std::vector*)obj; return v.empty(); } if( k == NONE ) return true; if( k == STD_VECTOR_VECTOR ) { const std::vector >& vv = *(const std::vector >*)obj; return vv.empty(); } if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; return vv.empty(); } if( k == STD_ARRAY_MAT ) { return sz.height == 0; } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; return vv.empty(); } if( k == OPENGL_BUFFER ) return ((const ogl::Buffer*)obj)->empty(); if( k == CUDA_GPU_MAT ) return ((const cuda::GpuMat*)obj)->empty(); if (k == STD_VECTOR_CUDA_GPU_MAT) { const std::vector& vv = *(const std::vector*)obj; return vv.empty(); } if( k == CUDA_HOST_MEM ) return ((const cuda::HostMem*)obj)->empty(); CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); return true; } bool _InputArray::isContinuous(int i) const { int k = kind(); if( k == MAT ) return i < 0 ? ((const Mat*)obj)->isContinuous() : true; if( k == UMAT ) return i < 0 ? ((const UMat*)obj)->isContinuous() : true; if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return true; if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].isContinuous(); } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; CV_Assert(i > 0 && i < sz.height); return vv[i].isContinuous(); } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].isContinuous(); } if( k == CUDA_GPU_MAT ) return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true; CV_Error(CV_StsNotImplemented, "Unknown/unsupported array type"); return false; } bool _InputArray::isSubmatrix(int i) const { int k = kind(); if( k == MAT ) return i < 0 ? ((const Mat*)obj)->isSubmatrix() : false; if( k == UMAT ) return i < 0 ? ((const UMat*)obj)->isSubmatrix() : false; if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return false; if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].isSubmatrix(); } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; CV_Assert(i < sz.height); return vv[i].isSubmatrix(); } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].isSubmatrix(); } CV_Error(CV_StsNotImplemented, ""); return false; } size_t _InputArray::offset(int i) const { int k = kind(); if( k == MAT ) { CV_Assert( i < 0 ); const Mat * const m = ((const Mat*)obj); return (size_t)(m->ptr() - m->datastart); } if( k == UMAT ) { CV_Assert( i < 0 ); return ((const UMat*)obj)->offset; } if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return 0; if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return 1; CV_Assert( i < (int)vv.size() ); return (size_t)(vv[i].ptr() - vv[i].datastart); } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; if( i < 0 ) return 1; CV_Assert( i < sz.height ); return (size_t)(vv[i].ptr() - vv[i].datastart); } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].offset; } if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); const cuda::GpuMat * const m = ((const cuda::GpuMat*)obj); return (size_t)(m->data - m->datastart); } if (k == STD_VECTOR_CUDA_GPU_MAT) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return (size_t)(vv[i].data - vv[i].datastart); } CV_Error(Error::StsNotImplemented, ""); return 0; } size_t _InputArray::step(int i) const { int k = kind(); if( k == MAT ) { CV_Assert( i < 0 ); return ((const Mat*)obj)->step; } if( k == UMAT ) { CV_Assert( i < 0 ); return ((const UMat*)obj)->step; } if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return 0; if( k == STD_VECTOR_MAT ) { const std::vector& vv = *(const std::vector*)obj; if( i < 0 ) return 1; CV_Assert( i < (int)vv.size() ); return vv[i].step; } if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; if( i < 0 ) return 1; CV_Assert( i < sz.height ); return vv[i].step; } if( k == STD_VECTOR_UMAT ) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].step; } if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); return ((const cuda::GpuMat*)obj)->step; } if (k == STD_VECTOR_CUDA_GPU_MAT) { const std::vector& vv = *(const std::vector*)obj; CV_Assert((size_t)i < vv.size()); return vv[i].step; } CV_Error(Error::StsNotImplemented, ""); return 0; } void _InputArray::copyTo(const _OutputArray& arr) const { int k = kind(); if( k == NONE ) arr.release(); else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == STD_BOOL_VECTOR ) { Mat m = getMat(); m.copyTo(arr); } else if( k == EXPR ) { const MatExpr& e = *((MatExpr*)obj); if( arr.kind() == MAT ) arr.getMatRef() = e; else Mat(e).copyTo(arr); } else if( k == UMAT ) ((UMat*)obj)->copyTo(arr); else CV_Error(Error::StsNotImplemented, ""); } void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) const { int k = kind(); if( k == NONE ) arr.release(); else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == STD_BOOL_VECTOR ) { Mat m = getMat(); m.copyTo(arr, mask); } else if( k == UMAT ) ((UMat*)obj)->copyTo(arr, mask); else CV_Error(Error::StsNotImplemented, ""); } bool _OutputArray::fixedSize() const { return (flags & FIXED_SIZE) == FIXED_SIZE; } bool _OutputArray::fixedType() const { return (flags & FIXED_TYPE) == FIXED_TYPE; } void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int fixedDepthMask) const { int k = kind(); if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz); CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype); ((Mat*)obj)->create(_sz, mtype); return; } if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == _sz); CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype); ((UMat*)obj)->create(_sz, mtype); return; } if( k == CUDA_GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == _sz); CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype); ((cuda::GpuMat*)obj)->create(_sz, mtype); return; } if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == _sz); CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype); ((ogl::Buffer*)obj)->create(_sz, mtype); return; } if( k == CUDA_HOST_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((cuda::HostMem*)obj)->size() == _sz); CV_Assert(!fixedType() || ((cuda::HostMem*)obj)->type() == mtype); ((cuda::HostMem*)obj)->create(_sz, mtype); return; } int sizes[] = {_sz.height, _sz.width}; create(2, sizes, mtype, i, allowTransposed, fixedDepthMask); } void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const { int k = kind(); if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows)); CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype); ((Mat*)obj)->create(_rows, _cols, mtype); return; } if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == Size(_cols, _rows)); CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype); ((UMat*)obj)->create(_rows, _cols, mtype); return; } if( k == CUDA_GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == Size(_cols, _rows)); CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype); ((cuda::GpuMat*)obj)->create(_rows, _cols, mtype); return; } if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == Size(_cols, _rows)); CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype); ((ogl::Buffer*)obj)->create(_rows, _cols, mtype); return; } if( k == CUDA_HOST_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 ) { CV_Assert(!fixedSize() || ((cuda::HostMem*)obj)->size() == Size(_cols, _rows)); CV_Assert(!fixedType() || ((cuda::HostMem*)obj)->type() == mtype); ((cuda::HostMem*)obj)->create(_rows, _cols, mtype); return; } int sizes[] = {_rows, _cols}; create(2, sizes, mtype, i, allowTransposed, fixedDepthMask); } void _OutputArray::create(int d, const int* sizes, int mtype, int i, bool allowTransposed, int fixedDepthMask) const { int k = kind(); mtype = CV_MAT_TYPE(mtype); if( k == MAT ) { CV_Assert( i < 0 ); Mat& m = *(Mat*)obj; if( allowTransposed ) { if( !m.isContinuous() ) { CV_Assert(!fixedType() && !fixedSize()); m.release(); } if( d == 2 && m.dims == 2 && m.data && 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()) { 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 == UMAT ) { CV_Assert( i < 0 ); UMat& m = *(UMat*)obj; if( allowTransposed ) { if( !m.isContinuous() ) { CV_Assert(!fixedType() && !fixedSize()); m.release(); } if( d == 2 && m.dims == 2 && !m.empty() && 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()) { 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 == MATX ) { CV_Assert( i < 0 ); int type0 = CV_MAT_TYPE(flags); CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) ); CV_Assert( d == 2 && ((sizes[0] == sz.height && sizes[1] == sz.width) || (allowTransposed && sizes[0] == sz.width && sizes[1] == sz.height))); return; } if( k == STD_ARRAY ) { int type0 = CV_MAT_TYPE(flags); CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) ); CV_Assert( d == 2 && sz.area() == sizes[0]*sizes[1]); return; } if( k == STD_VECTOR || k == STD_VECTOR_VECTOR ) { 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; std::vector* v = (std::vector*)obj; if( k == STD_VECTOR_VECTOR ) { std::vector >& vv = *(std::vector >*)obj; if( i < 0 ) { CV_Assert(!fixedSize() || len == vv.size()); vv.resize(len); return; } CV_Assert( i < (int)vv.size() ); v = &vv[i]; } else CV_Assert( i < 0 ); int type0 = CV_MAT_TYPE(flags); CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) ); int esz = CV_ELEM_SIZE(type0); CV_Assert(!fixedSize() || len == ((std::vector*)v)->size() / esz); switch( esz ) { case 1: ((std::vector*)v)->resize(len); break; case 2: ((std::vector*)v)->resize(len); break; case 3: ((std::vector*)v)->resize(len); break; case 4: ((std::vector*)v)->resize(len); break; case 6: ((std::vector*)v)->resize(len); break; case 8: ((std::vector*)v)->resize(len); break; case 12: ((std::vector*)v)->resize(len); break; case 16: ((std::vector*)v)->resize(len); break; case 24: ((std::vector*)v)->resize(len); break; case 32: ((std::vector*)v)->resize(len); break; case 36: ((std::vector >*)v)->resize(len); break; case 48: ((std::vector >*)v)->resize(len); break; case 64: ((std::vector >*)v)->resize(len); break; case 128: ((std::vector >*)v)->resize(len); break; case 256: ((std::vector >*)v)->resize(len); break; case 512: ((std::vector >*)v)->resize(len); break; default: CV_Error_(CV_StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); } return; } if( k == NONE ) { CV_Error(CV_StsNullPtr, "create() called for the missing output array" ); return; } if( k == STD_VECTOR_MAT ) { 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() ); Mat& m = v[i]; if( allowTransposed ) { if( !m.isContinuous() ) { CV_Assert(!fixedType() && !fixedSize()); m.release(); } if( d == 2 && m.dims == 2 && m.data && 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()) { 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_ARRAY_MAT ) { Mat* v = (Mat*)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 = sz.height; CV_Assert(len == len0); 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 < sz.height ); Mat& m = v[i]; if( allowTransposed ) { if( !m.isContinuous() ) { CV_Assert(!fixedType() && !fixedSize()); m.release(); } if( d == 2 && m.dims == 2 && m.data && 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()) { 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()) { 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; } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } void _OutputArray::createSameSize(const _InputArray& arr, int mtype) const { int arrsz[CV_MAX_DIM], d = arr.sizend(arrsz); create(d, arrsz, mtype); } void _OutputArray::release() const { CV_Assert(!fixedSize()); int k = kind(); if( k == MAT ) { ((Mat*)obj)->release(); return; } if( k == UMAT ) { ((UMat*)obj)->release(); return; } if( k == CUDA_GPU_MAT ) { ((cuda::GpuMat*)obj)->release(); return; } if( k == CUDA_HOST_MEM ) { ((cuda::HostMem*)obj)->release(); return; } if( k == OPENGL_BUFFER ) { ((ogl::Buffer*)obj)->release(); return; } if( k == NONE ) return; if( k == STD_VECTOR ) { create(Size(), CV_MAT_TYPE(flags)); return; } if( k == STD_VECTOR_VECTOR ) { ((std::vector >*)obj)->clear(); return; } if( k == STD_VECTOR_MAT ) { ((std::vector*)obj)->clear(); return; } if( k == STD_VECTOR_UMAT ) { ((std::vector*)obj)->clear(); return; } if (k == STD_VECTOR_CUDA_GPU_MAT) { ((std::vector*)obj)->clear(); return; } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } void _OutputArray::clear() const { int k = kind(); if( k == MAT ) { CV_Assert(!fixedSize()); ((Mat*)obj)->resize(0); return; } release(); } bool _OutputArray::needed() const { return kind() != NONE; } Mat& _OutputArray::getMatRef(int i) const { int k = kind(); if( i < 0 ) { CV_Assert( k == MAT ); return *(Mat*)obj; } CV_Assert( k == STD_VECTOR_MAT || k == STD_ARRAY_MAT ); if( k == STD_VECTOR_MAT ) { std::vector& v = *(std::vector*)obj; CV_Assert( i < (int)v.size() ); return v[i]; } else { Mat* v = (Mat*)obj; CV_Assert( 0 <= i && i < sz.height ); return v[i]; } } UMat& _OutputArray::getUMatRef(int i) const { int k = kind(); if( i < 0 ) { CV_Assert( k == UMAT ); return *(UMat*)obj; } else { CV_Assert( k == STD_VECTOR_UMAT ); std::vector& v = *(std::vector*)obj; CV_Assert( i < (int)v.size() ); return v[i]; } } cuda::GpuMat& _OutputArray::getGpuMatRef() const { int k = kind(); CV_Assert( k == CUDA_GPU_MAT ); return *(cuda::GpuMat*)obj; } std::vector& _OutputArray::getGpuMatVecRef() const { int k = kind(); CV_Assert(k == STD_VECTOR_CUDA_GPU_MAT); return *(std::vector*)obj; } ogl::Buffer& _OutputArray::getOGlBufferRef() const { int k = kind(); CV_Assert( k == OPENGL_BUFFER ); return *(ogl::Buffer*)obj; } cuda::HostMem& _OutputArray::getHostMemRef() const { int k = kind(); CV_Assert( k == CUDA_HOST_MEM ); return *(cuda::HostMem*)obj; } void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const { int k = kind(); if( k == NONE ) ; else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_ARRAY ) { Mat m = getMat(); m.setTo(arr, mask); } else if( k == UMAT ) ((UMat*)obj)->setTo(arr, mask); else if( k == CUDA_GPU_MAT ) { Mat value = arr.getMat(); CV_Assert( checkScalar(value, type(), arr.kind(), _InputArray::CUDA_GPU_MAT) ); ((cuda::GpuMat*)obj)->setTo(Scalar(Vec(value.ptr())), mask); } else CV_Error(Error::StsNotImplemented, ""); } void _OutputArray::assign(const UMat& u) const { int k = kind(); if (k == UMAT) { *(UMat*)obj = u; } else if (k == MAT) { u.copyTo(*(Mat*)obj); // TODO check u.getMat() } else if (k == MATX) { u.copyTo(getMat()); // TODO check u.getMat() } else { CV_Error(Error::StsNotImplemented, ""); } } void _OutputArray::assign(const Mat& m) const { int k = kind(); if (k == UMAT) { m.copyTo(*(UMat*)obj); // TODO check m.getUMat() } else if (k == MAT) { *(Mat*)obj = m; } else if (k == MATX) { m.copyTo(getMat()); } else { CV_Error(Error::StsNotImplemented, ""); } } void _OutputArray::assign(const std::vector& v) const { int k = kind(); if (k == STD_VECTOR_UMAT) { std::vector& this_v = *(std::vector*)obj; CV_Assert(this_v.size() == v.size()); for (size_t i = 0; i < v.size(); i++) { const UMat& m = v[i]; UMat& this_m = this_v[i]; if (this_m.u != NULL && this_m.u == m.u) continue; // same object (see dnn::Layer::forward_fallback) m.copyTo(this_m); } } else if (k == STD_VECTOR_MAT) { std::vector& this_v = *(std::vector*)obj; CV_Assert(this_v.size() == v.size()); for (size_t i = 0; i < v.size(); i++) { const UMat& m = v[i]; Mat& this_m = this_v[i]; if (this_m.u != NULL && this_m.u == m.u) continue; // same object (see dnn::Layer::forward_fallback) m.copyTo(this_m); } } else { CV_Error(Error::StsNotImplemented, ""); } } void _OutputArray::assign(const std::vector& v) const { int k = kind(); if (k == STD_VECTOR_UMAT) { std::vector& this_v = *(std::vector*)obj; CV_Assert(this_v.size() == v.size()); for (size_t i = 0; i < v.size(); i++) { const Mat& m = v[i]; UMat& this_m = this_v[i]; if (this_m.u != NULL && this_m.u == m.u) continue; // same object (see dnn::Layer::forward_fallback) m.copyTo(this_m); } } else if (k == STD_VECTOR_MAT) { std::vector& this_v = *(std::vector*)obj; CV_Assert(this_v.size() == v.size()); for (size_t i = 0; i < v.size(); i++) { const Mat& m = v[i]; Mat& this_m = this_v[i]; if (this_m.u != NULL && this_m.u == m.u) continue; // same object (see dnn::Layer::forward_fallback) m.copyTo(this_m); } } else { CV_Error(Error::StsNotImplemented, ""); } } static _InputOutputArray _none; InputOutputArray noArray() { return _none; } } // cv::