12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- // must be defined before importing numpy headers
- // https://numpy.org/doc/1.17/reference/c-api.array.html#importing-the-api
- #define NO_IMPORT_ARRAY
- #define PY_ARRAY_UNIQUE_SYMBOL opencv_ARRAY_API
- #include "cv2_numpy.hpp"
- #include "cv2_util.hpp"
- NumpyAllocator g_numpyAllocator;
- using namespace cv;
- UMatData* NumpyAllocator::allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const
- {
- UMatData* u = new UMatData(this);
- u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o);
- npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
- for( int i = 0; i < dims - 1; i++ )
- step[i] = (size_t)_strides[i];
- step[dims-1] = CV_ELEM_SIZE(type);
- u->size = sizes[0]*step[0];
- u->userdata = o;
- return u;
- }
- UMatData* NumpyAllocator::allocate(int dims0, const int* sizes, int type, void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const
- {
- if( data != 0 )
- {
- // issue #6969: CV_Error(Error::StsAssert, "The data should normally be NULL!");
- // probably this is safe to do in such extreme case
- return stdAllocator->allocate(dims0, sizes, type, data, step, flags, usageFlags);
- }
- PyEnsureGIL gil;
- int depth = CV_MAT_DEPTH(type);
- int cn = CV_MAT_CN(type);
- const int f = (int)(sizeof(size_t)/8);
- int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :
- depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :
- depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :
- depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;
- int i, dims = dims0;
- cv::AutoBuffer<npy_intp> _sizes(dims + 1);
- for( i = 0; i < dims; i++ )
- _sizes[i] = sizes[i];
- if( cn > 1 )
- _sizes[dims++] = cn;
- PyObject* o = PyArray_SimpleNew(dims, _sizes.data(), typenum);
- if(!o)
- CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
- return allocate(o, dims0, sizes, type, step);
- }
- bool NumpyAllocator::allocate(UMatData* u, AccessFlag accessFlags, UMatUsageFlags usageFlags) const
- {
- return stdAllocator->allocate(u, accessFlags, usageFlags);
- }
- void NumpyAllocator::deallocate(UMatData* u) const
- {
- if(!u)
- return;
- PyEnsureGIL gil;
- CV_Assert(u->urefcount >= 0);
- CV_Assert(u->refcount >= 0);
- if(u->refcount == 0)
- {
- PyObject* o = (PyObject*)u->userdata;
- Py_XDECREF(o);
- delete u;
- }
- }
|