1

I use python as an interface to operate the image, but when I need to write some custom functions to operate the matrix, I find out that numpy.ndarray is too slow when I iterate. I want to transfer the array to cv::Mat so that I can handle it easily because I used to write C++ code for image processing based on cv::Mat structure.

my test.cpp:

#include <Python.h>
#include <iostream>

using namespace std;

static PyObject *func(PyObject *self, PyObject *args) {
    printf("What should I write here?\n");
    // How to parse the args to get an np.ndarray?
    // cv::Mat m = whateverFunction(theParsedArray);
    return Py_BuildValue("s", "Any help?");
}

static PyMethodDef My_methods[] = {
    { "func", (PyCFunction) func, METH_VARARGS, NULL },
   { NULL, NULL, 0, NULL }
};

PyMODINIT_FUNC initydw_cvpy(void) {
    PyObject *m=Py_InitModule("ydw_cvpy", My_methods);

    if (m == NULL)
        return;
}

main.py:

if __name__ == '__main__':
    print ydw_cvpy.func()

Result:

What should I write here?
Any help?
Joel Vroom
  • 1,611
  • 1
  • 16
  • 30
Dawei Yang
  • 606
  • 1
  • 9
  • 19

1 Answers1

0

It's been a while since I've played with raw C python bindings (I usually use boost::python) but the key is PyArray_FromAny. Some untested sample code would look like

PyObject* source = /* somehow get this from the argument list */

PyArrayObject* contig = (PyArrayObject*)PyArray_FromAny(source,
        PyArray_DescrFromType(NPY_UINT8),
        2, 2, NPY_ARRAY_CARRAY, NULL);
if (contig == nullptr) {
  // Throw an exception
  return;
}

cv::Mat mat(PyArray_DIM(contig, 0), PyArray_DIM(contig, 1), CV_8UC1,
            PyArray_DATA(contig));

/* Use mat here */

PyDECREF(contig); // You can't use mat after this line

Note that this assumes that you have a an CV_8UC1 array. If you have a CV_8UC3 you need to ask for a 3 dimensional array

PyArrayObject* contig = (PyArrayObject*)PyArray_FromAny(source,
    PyArray_DescrFromType(NPY_UINT8),
    3, 3, NPY_ARRAY_CARRAY, NULL);
assert(contig && PyArray_DIM(contig, 2) == 3);

If you need to handle any random type of array, you probably also want to look at this answer.

Community
  • 1
  • 1
seeker
  • 1,136
  • 1
  • 13
  • 16