From a4c70aebd0c7a41a54e583e42df2435f63f3ec4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20W=C3=BCrtz?= Date: Wed, 19 Apr 2017 20:41:48 +0200 Subject: [PATCH 1/2] Expose UMat OpenCL handles and buffer information to python --- modules/python/src2/cv2.cpp | 60 ++++++++++++++++++++++++++++++++++++- modules/python/test/test.py | 19 ++++++++---- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index bfd23b7e78..1eb4533812 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -508,13 +508,71 @@ static PyObject * UMatWrapper_get(cv2_UMatWrapperObject* self) return pyopencv_from(m); } +// UMatWrapper.handle() - returns the OpenCL handle of the UMat object +static PyObject * UMatWrapper_handle(cv2_UMatWrapperObject* self, PyObject *args, PyObject *kwds) +{ + const char *kwlist[] = {"accessFlags", NULL}; + int accessFlags; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", (char**) kwlist, &accessFlags)) + return 0; + return PyLong_FromVoidPtr(self->um->handle(accessFlags)); +} + +// UMatWrapper.isContinuous() - returns true if the matrix data is continuous +static PyObject * UMatWrapper_isContinuous(cv2_UMatWrapperObject* self) +{ + return PyBool_FromLong(self->um->isContinuous()); +} + +// UMatWrapper.isContinuous() - returns true if the matrix is a submatrix of another matrix +static PyObject * UMatWrapper_isSubmatrix(cv2_UMatWrapperObject* self) +{ + return PyBool_FromLong(self->um->isSubmatrix()); +} + +// UMatWrapper.context() - returns the OpenCL context used by OpenCV UMat +static PyObject * UMatWrapper_context(cv2_UMatWrapperObject*) +{ + return PyLong_FromVoidPtr(cv::ocl::Context::getDefault().ptr()); +} + +// UMatWrapper.context() - returns the OpenCL queue used by OpenCV UMat +static PyObject * UMatWrapper_queue(cv2_UMatWrapperObject*) +{ + return PyLong_FromVoidPtr(cv::ocl::Queue::getDefault().ptr()); +} + +static PyObject * UMatWrapper_offset_getter(cv2_UMatWrapperObject* self, void*) +{ + return PyLong_FromSsize_t(self->um->offset); +} + static PyMethodDef UMatWrapper_methods[] = { {"get", (PyCFunction)UMatWrapper_get, METH_NOARGS, "Returns numpy array" }, + {"handle", (PyCFunction)UMatWrapper_handle, METH_VARARGS | METH_KEYWORDS, + "Returns UMat native handle" + }, + {"isContinuous", (PyCFunction)UMatWrapper_isContinuous, METH_NOARGS, + "Returns true if the matrix data is continuous" + }, + {"isSubmatrix", (PyCFunction)UMatWrapper_isSubmatrix, METH_NOARGS, + "Returns true if the matrix is a submatrix of another matrix" + }, + {"context", (PyCFunction)UMatWrapper_context, METH_NOARGS | METH_STATIC, + "Returns OpenCL context handle" + }, + {"queue", (PyCFunction)UMatWrapper_queue, METH_NOARGS | METH_STATIC, + "Returns OpenCL queue handle" + }, {NULL, NULL, 0, NULL} /* Sentinel */ }; +static PyGetSetDef UMatWrapper_getset[] = { + {(char*) "offset", (getter) UMatWrapper_offset_getter, NULL, NULL, NULL}, + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ +}; static PyTypeObject cv2_UMatWrapperType = { #if PY_MAJOR_VERSION >= 3 @@ -551,7 +609,7 @@ static PyTypeObject cv2_UMatWrapperType = { 0, /* tp_iternext */ UMatWrapper_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + UMatWrapper_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ diff --git a/modules/python/test/test.py b/modules/python/test/test.py index f4585471e8..be3f821aa9 100755 --- a/modules/python/test/test.py +++ b/modules/python/test/test.py @@ -127,12 +127,21 @@ class Hackathon244Tests(NewOpenCVTests): data = np.random.random([512, 512]) # UMat constructors data_um = cv2.UMat(data) # from ndarray - data_sub_um = cv2.UMat(data_um, [0, 256], [0, 256]) # from UMat - data_dst_um = cv2.UMat(256, 256, cv2.CV_64F) # from size/type - - # simple test + data_sub_um = cv2.UMat(data_um, [128, 256], [128, 256]) # from UMat + data_dst_um = cv2.UMat(128, 128, cv2.CV_64F) # from size/type + # test continuous and submatrix flags + assert data_um.isContinuous() and not data_um.isSubmatrix() + assert not data_sub_um.isContinuous() and data_sub_um.isSubmatrix() + # test operation on submatrix cv2.multiply(data_sub_um, 2., dst=data_dst_um) - assert np.allclose(2. * data[:256, :256], data_dst_um.get()) + assert np.allclose(2. * data[128:256, 128:256], data_dst_um.get()) + + def test_umat_handle(self): + a_um = cv2.UMat(256, 256, cv2.CV_32F) + ctx_handle = cv2.UMat.context() # obtain context handle + queue_handle = cv2.UMat.queue() # obtain queue handle + a_handle = a_um.handle(cv2.ACCESS_READ) # obtain buffer handle + offset = a_um.offset # obtain buffer offset def test_umat_matching(self): img1 = self.get_sample("samples/data/right01.jpg") From 4c095a76c03a5a233c5bd54fccea98a80316c8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20W=C3=BCrtz?= Date: Fri, 21 Apr 2017 12:21:54 +0200 Subject: [PATCH 2/2] Add docstring for UMat::handle --- modules/core/include/opencv2/core/mat.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 0a74e72817..d8adaeed04 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -2464,6 +2464,10 @@ public: UMat& operator = (UMat&& m); #endif + /*! Returns the OpenCL buffer handle on which UMat operates on. + The UMat instance should be kept alive during the use of the handle to prevent the buffer to be + returned to the OpenCV buffer pool. + */ void* handle(int accessFlags) const; void ndoffset(size_t* ofs) const;