Pass Mat to Python Script ?
Hi, I am using OpenCV v2.4.13.6 with C++ in QT Creator. I am trying to pass an OpenCV Mat object to a Python script using Python interpreter. I need to convert the OpenCV Mat to a PyObject so that I can pass it to the Python script.
Something like this:
PyObject *pName, *pModule, *pFunc, *pValue, *pMat;
Mat img;
Py_Initialize();
pName = PyUnicode_FromString("load-mat"); //python script is named load-mat
pModule = PyImport_Import(pName);
pFunc = PyObject_GetAttrString(pModule, "load_mat") //python function is named load_mat()
############################################
//Need to convert Mat img to PyObject *pMat
############################################
pValue = PyObject_CallFunctionObjArgs(pFunc, pMat, NULL);
Py_Finalize();
I read somewhere:
PyObject* pyopencv_from(const cv::Mat& m)
{
if( !m.data )
Py_RETURN_NONE;
cv::Mat temp, *p = (cv::Mat*)&m;
if(!p->refcount || p->allocator != &g_numpyAllocator)
{
temp.allocator = &g_numpyAllocator;
m.copyTo(temp);
p = &temp;
}
p->addref();
return pyObjectFromRefcount(p->refcount);
}
pMat = pyopencv_from(img);
But placing that into my C++ code straight I get the following 2 errors:
error: 'g_numpyAllocator' was not declared in this scope
error: 'pyObjectFromRefcount' was not declared in this scope
What is the easiest method of getting this to work ? Thanks
oh, noes, don't try to write your own wrapper.
WHY do you (think, you) need to do this ?
v2.4.13.6 -- outdated. (frozen in the state of ~5 years ago) why do you use that ?
Hi, I'm not trying to write my own wrapper. I was just following the guide here: Embedding Python in Another Application. I had trouble building OpenCV v3 from source for MinGW x64 compiler. What's wrong with using OpenCV v2 ?
if you start like this, sure you do !
again, why do you need it ?
(there's also a problem: if you use cv2 AND your own wrappers, you have 2 (different) opencv versions in your program)
maybe you're better off, adding another module (with your c++ code & headers) to the opencv codebase, and let the python generator do it's job. then, also, cv::Mat is already correctly wrapped there. (no need to do that again)
have a look here and try to explain better, where you start from, and what you're trying to achieve, please.
Ok, maybe it's better for me to explain at a high level what I'm trying to achieve, then you can let me know if it's possible.
1) I have a script in Python that trains a classifier on pre-loaded images. I have another Python script that should take as input an OpenCV image and pass it through the classifier (which I load from file) to produce a prediction. This Python script/function is the one I am referring to in my code.
2) I have a C++ program that gets the OpenCV image that I wish to pass through the classifier.
Basically the classification is in Python but the image that I wish to classify is in my C++ program. So somehow I need to pass the Mat image that I have in C++ to the Python script for classification and have it return the prediction result ...(more)
ah, i missed the "embedding" part. that's the other side of the table.
i still think, it's a bad idea. why are there even 3 seperate programs ? can't you replace the c++ image acquisition with something in python ?
No, I need to use C++ because it's a GUI program. I cannot convert the python code to C++ either.
There are 3 programs because 1. is for the main GUI program that captures images, 2. is a python script for training a classifier (as I said already, this cannot be re-written in C++ with ease - it's a complex CNN), and 3. is for loading the trained classifier and performing forward-pass prediction on a given image.
If I can just convert my Mat object to a PyObject in the C++ program then I can pass it to the python script for prediction. Surely this is possible ? Yes, it may not be the best idea, but I think it should be possible. Maybe with something like the "pyopencv_from()" function ?
@berak Anymore info on this ?
no, sorry.
@berak I'm using the built in OpenCV wrapper
pyopencv_from()
included in "modules\python\src2\cv2" to wrap the Mat as a Numpy Array but my program crashes on the linePyObject* o = PyArray_SimpleNew(dims, _sizes, typenum);
Any idea why ?Nevermind, I solved it by adding the line:
import_array();
to my main function.