cv2_numpy.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // must be defined before importing numpy headers
  2. // https://numpy.org/doc/1.17/reference/c-api.array.html#importing-the-api
  3. #define NO_IMPORT_ARRAY
  4. #define PY_ARRAY_UNIQUE_SYMBOL opencv_ARRAY_API
  5. #include "cv2_numpy.hpp"
  6. #include "cv2_util.hpp"
  7. NumpyAllocator g_numpyAllocator;
  8. using namespace cv;
  9. UMatData* NumpyAllocator::allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const
  10. {
  11. UMatData* u = new UMatData(this);
  12. u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o);
  13. npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
  14. for( int i = 0; i < dims - 1; i++ )
  15. step[i] = (size_t)_strides[i];
  16. step[dims-1] = CV_ELEM_SIZE(type);
  17. u->size = sizes[0]*step[0];
  18. u->userdata = o;
  19. return u;
  20. }
  21. UMatData* NumpyAllocator::allocate(int dims0, const int* sizes, int type, void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const
  22. {
  23. if( data != 0 )
  24. {
  25. // issue #6969: CV_Error(Error::StsAssert, "The data should normally be NULL!");
  26. // probably this is safe to do in such extreme case
  27. return stdAllocator->allocate(dims0, sizes, type, data, step, flags, usageFlags);
  28. }
  29. PyEnsureGIL gil;
  30. int depth = CV_MAT_DEPTH(type);
  31. int cn = CV_MAT_CN(type);
  32. const int f = (int)(sizeof(size_t)/8);
  33. int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :
  34. depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :
  35. depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :
  36. depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;
  37. int i, dims = dims0;
  38. cv::AutoBuffer<npy_intp> _sizes(dims + 1);
  39. for( i = 0; i < dims; i++ )
  40. _sizes[i] = sizes[i];
  41. if( cn > 1 )
  42. _sizes[dims++] = cn;
  43. PyObject* o = PyArray_SimpleNew(dims, _sizes.data(), typenum);
  44. if(!o)
  45. CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
  46. return allocate(o, dims0, sizes, type, step);
  47. }
  48. bool NumpyAllocator::allocate(UMatData* u, AccessFlag accessFlags, UMatUsageFlags usageFlags) const
  49. {
  50. return stdAllocator->allocate(u, accessFlags, usageFlags);
  51. }
  52. void NumpyAllocator::deallocate(UMatData* u) const
  53. {
  54. if(!u)
  55. return;
  56. PyEnsureGIL gil;
  57. CV_Assert(u->urefcount >= 0);
  58. CV_Assert(u->refcount >= 0);
  59. if(u->refcount == 0)
  60. {
  61. PyObject* o = (PyObject*)u->userdata;
  62. Py_XDECREF(o);
  63. delete u;
  64. }
  65. }