Rewrite the UMat Python wrapper

This commit is contained in:
Hamdi Sahloul
2018-08-25 07:19:14 +09:00
parent 2bbe31a8f6
commit 669ee0415a
4 changed files with 97 additions and 281 deletions
-280
View File
@@ -554,275 +554,6 @@ PyObject* pyopencv_from(const cv::Ptr<T>& p)
return pyopencv_from(*p);
}
typedef struct {
PyObject_HEAD
UMat* um;
} cv2_UMatWrapperObject;
static bool PyObject_IsUMat(PyObject *o);
// UMatWrapper init - try to map arguments from python to UMat constructors
static int UMatWrapper_init(PyObject* self_, PyObject *args, PyObject *kwds)
{
cv2_UMatWrapperObject* self = (cv2_UMatWrapperObject*)self_;
if (self == NULL)
{
PyErr_SetString(PyExc_TypeError, "Internal error");
return -1;
}
self->um = NULL;
{
// constructor ()
const char *kwlist[] = {NULL};
if (PyArg_ParseTupleAndKeywords(args, kwds, "", (char**) kwlist)) {
self->um = new UMat();
return 0;
}
PyErr_Clear();
}
{
// constructor (rows, cols, type)
const char *kwlist[] = {"rows", "cols", "type", NULL};
int rows, cols, type;
if (PyArg_ParseTupleAndKeywords(args, kwds, "iii", (char**) kwlist, &rows, &cols, &type)) {
self->um = new UMat(rows, cols, type);
return 0;
}
PyErr_Clear();
}
{
// constructor (m, rowRange, colRange)
const char *kwlist[] = {"m", "rowRange", "colRange", NULL};
PyObject *obj = NULL;
int y0 = -1, y1 = -1, x0 = -1, x1 = -1;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O(ii)|(ii)", (char**) kwlist, &obj, &y0, &y1, &x0, &x1) && PyObject_IsUMat(obj)) {
UMat *um_other = ((cv2_UMatWrapperObject *) obj)->um;
Range rowRange(y0, y1);
Range colRange = (x0 >= 0 && x1 >= 0) ? Range(x0, x1) : Range::all();
self->um = new UMat(*um_other, rowRange, colRange);
return 0;
}
PyErr_Clear();
}
{
// constructor (m)
const char *kwlist[] = {"m", NULL};
PyObject *obj = NULL;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O", (char**) kwlist, &obj)) {
// constructor (UMat m)
if (PyObject_IsUMat(obj)) {
UMat *um_other = ((cv2_UMatWrapperObject *) obj)->um;
self->um = new UMat(*um_other);
return 0;
}
// python specific constructor from array like object
Mat m;
if (pyopencv_to(obj, m, ArgInfo("UMatWrapper.np_mat", 0))) {
self->um = new UMat();
m.copyTo(*self->um);
return 0;
}
}
PyErr_Clear();
}
PyErr_SetString(PyExc_TypeError, "no matching UMat constructor found/supported");
return -1;
}
static void UMatWrapper_dealloc(cv2_UMatWrapperObject* self)
{
if (self->um)
delete self->um;
#if PY_MAJOR_VERSION >= 3
Py_TYPE(self)->tp_free((PyObject*)self);
#else
self->ob_type->tp_free((PyObject*)self);
#endif
}
// UMatWrapper.get() - returns numpy array by transferring UMat data to Mat and than wrapping it to numpy array
// (using numpy allocator - and so without unnecessary copy)
static PyObject * UMatWrapper_get(PyObject* self_, PyObject * /*args*/)
{
cv2_UMatWrapperObject* self = (cv2_UMatWrapperObject*)self_;
if (self == NULL)
return failmsgp("Incorrect type of self (must be 'cv2_UMatWrapperObject')");
Mat m;
m.allocator = &g_numpyAllocator;
self->um->copyTo(m);
return pyopencv_from(m);
}
// UMatWrapper.handle() - returns the OpenCL handle of the UMat object
static PyObject * UMatWrapper_handle(PyObject* self_, PyObject *args, PyObject *kwds)
{
cv2_UMatWrapperObject* self = (cv2_UMatWrapperObject*)self_;
if (self == NULL)
return failmsgp("Incorrect type of self (must be 'cv2_UMatWrapperObject')");
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(PyObject* self_, PyObject * /*args*/)
{
cv2_UMatWrapperObject* self = (cv2_UMatWrapperObject*)self_;
if (self == NULL)
return failmsgp("Incorrect type of self (must be 'cv2_UMatWrapperObject')");
return PyBool_FromLong(self->um->isContinuous());
}
// UMatWrapper.isContinuous() - returns true if the matrix is a submatrix of another matrix
static PyObject * UMatWrapper_isSubmatrix(PyObject* self_, PyObject * /*args*/)
{
cv2_UMatWrapperObject* self = (cv2_UMatWrapperObject*)self_;
if (self == NULL)
return failmsgp("Incorrect type of self (must be 'cv2_UMatWrapperObject')");
return PyBool_FromLong(self->um->isSubmatrix());
}
// UMatWrapper.context() - returns the OpenCL context used by OpenCV UMat
static PyObject * UMatWrapper_context(PyObject* /*self_*/, PyObject * /*args*/)
{
return PyLong_FromVoidPtr(cv::ocl::Context::getDefault().ptr());
}
// UMatWrapper.context() - returns the OpenCL queue used by OpenCV UMat
static PyObject * UMatWrapper_queue(PyObject* /*self_*/, PyObject * /*args*/)
{
return PyLong_FromVoidPtr(cv::ocl::Queue::getDefault().ptr());
}
static PyObject * UMatWrapper_offset_getter(PyObject* self_, void*)
{
cv2_UMatWrapperObject* self = (cv2_UMatWrapperObject*)self_;
if (self == NULL)
return failmsgp("Incorrect type of self (must be 'cv2_UMatWrapperObject')");
return PyLong_FromSsize_t(self->um->offset);
}
static PyMethodDef UMatWrapper_methods[] = {
{"get", CV_PY_FN_NOARGS(UMatWrapper_get),
"Returns numpy array"
},
{"handle", CV_PY_FN_WITH_KW(UMatWrapper_handle),
"Returns UMat native handle"
},
{"isContinuous", CV_PY_FN_NOARGS(UMatWrapper_isContinuous),
"Returns true if the matrix data is continuous"
},
{"isSubmatrix", CV_PY_FN_NOARGS(UMatWrapper_isSubmatrix),
"Returns true if the matrix is a submatrix of another matrix"
},
{"context", CV_PY_FN_NOARGS_(UMatWrapper_context, METH_STATIC),
"Returns OpenCL context handle"
},
{"queue", CV_PY_FN_NOARGS_(UMatWrapper_queue, 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
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
#endif
"cv2.UMat", /* tp_name */
sizeof(cv2_UMatWrapperObject), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)UMatWrapper_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"OpenCV 3 UMat wrapper. Used for T-API support.", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
UMatWrapper_methods, /* tp_methods */
0, /* tp_members */
UMatWrapper_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)UMatWrapper_init, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0, /* tp_del */
0, /* tp_version_tag */
#if PY_MAJOR_VERSION >= 3
0, /* tp_finalize */
#endif
};
static bool PyObject_IsUMat(PyObject *o) {
return (o != NULL) && PyObject_TypeCheck(o, &cv2_UMatWrapperType);
}
static bool pyopencv_to(PyObject* o, UMat& um, const ArgInfo info) {
if (PyObject_IsUMat(o)) {
um = *((cv2_UMatWrapperObject *) o)->um;
return true;
}
Mat m;
if (!pyopencv_to(o, m, info)) {
return false;
}
m.copyTo(um);
return true;
}
template<>
bool pyopencv_to(PyObject* o, UMat& um, const char* name)
{
return pyopencv_to(o, um, ArgInfo(name, 0));
}
template<>
PyObject* pyopencv_from(const UMat& m)
{
PyObject *o = PyObject_CallObject((PyObject *) &cv2_UMatWrapperType, NULL);
*((cv2_UMatWrapperObject *) o)->um = m;
return o;
}
template<>
bool pyopencv_to(PyObject* obj, void*& ptr, const char* name)
{
@@ -2060,15 +1791,6 @@ void initcv2()
Py_DECREF(opencv_error_dict);
PyDict_SetItemString(d, "error", opencv_error);
//Registering UMatWrapper python class in cv2 module:
if (PyType_Ready(&cv2_UMatWrapperType) < 0)
#if PY_MAJOR_VERSION >= 3
return NULL;
#else
return;
#endif
#if PY_MAJOR_VERSION >= 3
#define PUBLISH_OBJECT(name, type) Py_INCREF(&type);\
PyModule_AddObject(m, name, (PyObject *)&type);
@@ -2079,8 +1801,6 @@ void initcv2()
PyModule_AddObject(m, name, (PyObject *)&type);
#endif
PUBLISH_OBJECT("UMat", cv2_UMatWrapperType);
#include "pyopencv_generated_type_publish.h"
#define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I))
+1 -1
View File
@@ -12,7 +12,7 @@ class UMat(NewOpenCVTests):
data = np.random.random([512, 512])
# UMat constructors
data_um = cv.UMat(data) # from ndarray
data_sub_um = cv.UMat(data_um, [128, 256], [128, 256]) # from UMat
data_sub_um = cv.UMat(data_um, (128, 256), (128, 256)) # from UMat
data_dst_um = cv.UMat(128, 128, cv.CV_64F) # from size/type
# test continuous and submatrix flags
assert data_um.isContinuous() and not data_um.isSubmatrix()