python mat函数的作用,通过Mat / Numpy转换向Python公开基于OpenCV的C ++函数

I've ran into a problem trying to expose dynamic C++ library functions, linked to OpenCV and using OpenCV's Mat datatype, to Python 2.7 with the use of Numpy ndarray.

I've come up with a solution similar to lightalchemist's solution here and I've also tried using boost::python and boost::numpy (also linked to Python 2.7) described in this SO question.

Right now I'm sticking with the former. I've got to a point where I can load the module in iPython, and I see a function I'm trying to port using the inspect module, I can even call it and it even executes. However, the problem occurs specifically when I try to use the NumpyAllocator (see lightalchemist's solution) class to convert the Mat object back to ndarray.

Firstly, when I try to call pyopencv_from function from an outside C++ executable, and it uses the NumpyAllocator as it's coded, it segfaults at

PyEnsureGIL gil;

, with no message, every time. Lightalchemist's solution doesn't use it in pyopencv_to (EDIT: if the ndarray passed-in is already allocated), and it seems to work. However, the official OpenCV cv2.cpp does use the allocator in that as well, so if I try to use that the function can't even convert the input ndarray to Mat.

When I try to use the module from iPython, it sees the function. Again, it executes it correctly (prints progress to the console), but when it reaches the pyopencv_from, it segfaults and kills the iPython shell.

EDIT: I'm using exaclty the same source as lightalchemist, except I'm exposing a single function, the same way as the official OpenCV port does:

static PyMethodDef methods[] = {

{"findEdgesCGTG", (PyCFunction)pycvex_findEdgesCGTG, METH_KEYWORDS, "findEdgesCGTG(source) -> edgeGradient, edgeOrientations"},

{NULL, NULL}

};

extern "C"

#if defined WIN32 || defined _WIN32

__declspec(dllexport)

#endif

void initcvex()

{

import_array();

PyObject* m = Py_InitModule(MODULESTR, methods);

PyObject* d = PyModule_GetDict(m);

opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, NULL);

PyDict_SetItemString(d, "error", opencv_error);

}

Does anyone have any clue on how to resolve this conversion problem?

解决方案

The problem was not the

PyEnsureGIL gil;

statement. That only didn't work if I tried to use an external C++ function. The problem actually happened when I tried to pack two output values into one here:

return Py_BuildValue("(NN)", pyopencv_from(edgeGrad), pyopencv_from(edgeOri));

The temporary work-around was just to use the following statement:

return pyopencv_from(edgeGrad);

EDIT:

Sorry, I messed up again. The Py_BuildValue works just fine. Just tested my function again, it works perfectly. I must have forgotten to put the return keyword last time I tested it, so it gave me "error return without exception set."

Here's the full function code (I hope it's useful for anyone porting OpenCV stuff to python)

static PyObject* pycvex_findEdgesCGTG(PyObject* , PyObject* args, PyObject* kw)

{

PyObject* pyobj_source = NULL;

Mat source;

Mat edgeGrad;

Mat edgeOri;

const char* keywords[] = { "src", NULL };

if( PyArg_ParseTupleAndKeywords(args, kw, "O:findEdgesCGTG", (char**)keywords, &pyobj_source) &&

pyopencv_to(pyobj_source, source));

{

ERRWRAP2(findEdgesCGTG(source,edgeGrad,edgeOri));

return Py_BuildValue("(NN)", pyopencv_from(edgeGrad), pyopencv_from(edgeOri));

}

return NULL;

}

UPDATE:

Here is the github repo with the open C++ code I wrote for exposing code using OpenCV's Mat class with as little pain as possible. This is for OpenCV 3.X.

For OpenCV 2.X you can use this code / example by Yati Sagade. If you'd like to expose functions using the opencv Mat class without worrying about explicit conversions, it's easy to adapt the Booost converters from my code with the conversion functions in Yati's code.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值