1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge pull request #23913 from chacha21:GpuMatND_InputOutputArray

make cuda::GpuMatND compatible with InputArray/OutputArray #23913

continuation of  [PR#19259](https://github.com/opencv/opencv/pull/19259) 

Make cuda::GpuMatND wrappable in InputArray/OutputArray
The goal for now is just wrapping, some functions are not supported (InputArray::size(), InputArray::convertTo(), InputArray::assign()...)

No new feature for cuda::GpuMatND

- [X] I agree to contribute to the project under Apache 2 License.
- [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [X] The PR is proposed to the proper branch
- [X] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Pierre Chatelier
2025-11-21 06:41:12 +01:00
committed by GitHub
parent b90041b30a
commit fdf0332954
4 changed files with 166 additions and 3 deletions
+138
View File
@@ -111,6 +111,12 @@ Mat _InputArray::getMat_(int i) const
CV_Error(cv::Error::StsNotImplemented, "You should explicitly call download method for cuda::GpuMat object");
}
if( k == CUDA_GPU_MATND )
{
CV_Assert( i < 0 );
CV_Error(cv::Error::StsNotImplemented, "You should explicitly call download method for cuda::GpuMatND object");
}
if( k == CUDA_HOST_MEM )
{
CV_Assert( i < 0 );
@@ -357,6 +363,22 @@ void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
cuda::GpuMatND _InputArray::getGpuMatND() const
{
#ifdef HAVE_CUDA
_InputArray::KindFlag k = kind();
if (k == CUDA_GPU_MATND)
{
const cuda::GpuMatND* d_mat = (const cuda::GpuMatND*)obj;
return *d_mat;
}
CV_Error(cv::Error::StsNotImplemented, "getGpuMatND is available only for cuda::GpuMatND");
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
ogl::Buffer _InputArray::getOGlBuffer() const
{
_InputArray::KindFlag k = kind();
@@ -379,11 +401,29 @@ _InputArray::KindFlag _InputArray::kind() const
int _InputArray::rows(int i) const
{
#ifdef HAVE_CUDA
_InputArray::KindFlag k = kind();
if (k == CUDA_GPU_MATND)
{
const cuda::GpuMatND& _gpuMatND = *(const cuda::GpuMatND*)obj;
return (_gpuMatND.dims < 1) ? 0 : _gpuMatND.size[0];
}
#endif
return size(i).height;
}
int _InputArray::cols(int i) const
{
#ifdef HAVE_CUDA
_InputArray::KindFlag k = kind();
if (k == CUDA_GPU_MATND)
{
const cuda::GpuMatND& _gpuMatND = *(const cuda::GpuMatND*)obj;
return (_gpuMatND.dims < 2) ? 0 : _gpuMatND.size[1];
}
#endif
return size(i).width;
}
@@ -604,8 +644,13 @@ bool _InputArray::sameSize(const _InputArray& arr) const
return false;
sz1 = m->size();
}
else if ( (k1 == CUDA_GPU_MATND) && (k2 == CUDA_GPU_MATND))
{
return ((const cuda::GpuMatND*)obj)->size == ((const cuda::GpuMatND*)arr.obj)->size;
}
else
sz1 = size();
if( arr.dims() > 2 )
return false;
return sz1 == arr.size();
@@ -693,6 +738,12 @@ int _InputArray::dims(int i) const
return 2;
}
if( k == CUDA_GPU_MATND )
{
CV_Assert( i < 0 );
return ((const cuda::GpuMatND*)obj)->dims;
}
if( k == CUDA_HOST_MEM )
{
CV_Assert( i < 0 );
@@ -748,6 +799,21 @@ size_t _InputArray::total(int i) const
return vv[i].total();
}
if( k == CUDA_GPU_MATND )
{
CV_Assert( i < 0 );
size_t res = 0;
const cuda::GpuMatND& _gpuMatND = *((const cuda::GpuMatND*)obj);
if (_gpuMatND.dims > 0)
{
res = 1;
for(int d = 0 ; d<_gpuMatND.dims ; ++d)
res *= _gpuMatND.size[d];
return res;
}
}
return size(i).area();
}
@@ -825,6 +891,9 @@ int _InputArray::type(int i) const
if( k == CUDA_GPU_MAT )
return ((const cuda::GpuMat*)obj)->type();
if( k == CUDA_GPU_MATND )
return ((const cuda::GpuMatND*)obj)->type();
if( k == CUDA_HOST_MEM )
return ((const cuda::HostMem*)obj)->type();
@@ -904,6 +973,9 @@ bool _InputArray::empty() const
return vv.empty();
}
if( k == CUDA_GPU_MATND )
return ((const cuda::GpuMatND*)obj)->empty();
if( k == CUDA_HOST_MEM )
return ((const cuda::HostMem*)obj)->empty();
@@ -948,6 +1020,9 @@ bool _InputArray::isContinuous(int i) const
if( k == CUDA_GPU_MAT )
return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true;
if( k == CUDA_GPU_MATND )
return i < 0 ? ((const cuda::GpuMatND*)obj)->isContinuous() : true;
CV_Error(cv::Error::StsNotImplemented, "Unknown/unsupported array type");
}
@@ -986,6 +1061,11 @@ bool _InputArray::isSubmatrix(int i) const
return vv[i].isSubmatrix();
}
if( k == CUDA_GPU_MATND )
{
return ((const cuda::GpuMatND*)obj)->isSubmatrix();
}
CV_Error(cv::Error::StsNotImplemented, "");
}
@@ -1101,6 +1181,12 @@ size_t _InputArray::step(int i) const
CV_Assert(i >= 0 && (size_t)i < vv.size());
return vv[i].step;
}
if( k == CUDA_GPU_MATND )
{
const cuda::GpuMatND& _gpuMatND = *(const cuda::GpuMatND*)obj;
CV_Assert( i >= _gpuMatND.dims );
return _gpuMatND.step[i];
}
CV_Error(Error::StsNotImplemented, "");
}
@@ -1183,6 +1269,18 @@ void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, _Out
return;
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
if( k == CUDA_GPU_MATND && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
CV_Assert(!fixedSize() || ((((cuda::GpuMatND*)obj)->dims == 2) && (((cuda::GpuMatND*)obj)->size[0] == _sz.height) && (((cuda::GpuMatND*)obj)->size[1] == _sz.width)));
CV_Assert(!fixedType() || ((cuda::GpuMatND*)obj)->type() == mtype);
#ifdef HAVE_CUDA
cuda::GpuMatND::SizeArray sizes = {_sz.height, _sz.width};
((cuda::GpuMatND*)obj)->create(sizes, mtype);
return;
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
@@ -1237,6 +1335,18 @@ void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTran
return;
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
if( k == CUDA_GPU_MATND && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
CV_Assert(!fixedSize() || ((((cuda::GpuMatND*)obj)->dims == 2) && (((cuda::GpuMatND*)obj)->size[0] == _rows) && (((cuda::GpuMatND*)obj)->size[1] == _cols)));
CV_Assert(!fixedType() || ((cuda::GpuMatND*)obj)->type() == mtype);
#ifdef HAVE_CUDA
cuda::GpuMatND::SizeArray sizes = {_rows, _cols};
((cuda::GpuMatND*)obj)->create(sizes, mtype);
return;
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
@@ -1653,6 +1763,18 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
return;
}
if( k == CUDA_GPU_MATND && d > 0 && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
#ifdef HAVE_CUDA
cuda::GpuMatND::SizeArray sizeArray = cuda::GpuMatND::SizeArray(sizes, sizes+d);
((cuda::GpuMatND*)obj)->create(sizeArray, mtype);
return;
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type");
}
@@ -1696,6 +1818,16 @@ void _OutputArray::release() const
#endif
}
if( k == CUDA_GPU_MATND )
{
#ifdef HAVE_CUDA
((cuda::GpuMatND*)obj)->release();
return;
#else
CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)");
#endif
}
if( k == CUDA_HOST_MEM )
{
#ifdef HAVE_CUDA
@@ -1827,6 +1959,12 @@ std::vector<cuda::GpuMat>& _OutputArray::getGpuMatVecRef() const
CV_Assert(k == STD_VECTOR_CUDA_GPU_MAT);
return *(std::vector<cuda::GpuMat>*)obj;
}
cuda::GpuMatND& _OutputArray::getGpuMatNDRef() const
{
_InputArray::KindFlag k = kind();
CV_Assert( k == CUDA_GPU_MATND );
return *(cuda::GpuMatND*)obj;
}
ogl::Buffer& _OutputArray::getOGlBufferRef() const
{