1

I am reading an image as cv2.imread("abc.tiff",1) from my python interface, I want to pass this to c++ function which is binded by pybind11. The C++ function requires a cv::Mat as input.

Now I learned that python transforms that to NumPY , a NxM 3D array

I find the data height, width, channels as 5504 8256 3 respectively.

Any help me how do I find the solution for it.


Same again I need to pass a cv::Mat to Python interface

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
  • AFAIK, there is no standard method for it. Do you have to use cv::Mat? For example, you can call the cv::imread in C++ rather than python and simply pass the filename string to C++ rather than the matrix. On the return side, you could return the cv::Mat as an array and construct a numpy ndarray from it in the interface. – mahesh Aug 14 '18 at 09:20
  • Thanks @mahesh; main req is passing the cv::Mat from 1 pybind11 interface to another. Can you give me some idea how do I send the numpy ndarray from python , and transfer that to cv::Mat in c++ – humble_aspirant Aug 14 '18 at 09:54
  • You can use the buffers directly. So reshape the numpy array into a vector and pass the 1D array along with the dimensions to the C++ interface. Within the C++ code, convert the 1D array into a cv::Mat using also the dimensions passed from python. Reverse the process in the other direction (C++ to python). You might find this helpful: https://github.com/yati-sagade/opencv-ndarray-conversion/blob/master/conversion.cpp – mahesh Aug 14 '18 at 10:30

1 Answers1

3

For the python numpy -> c++ cv2 I found a way how to do it via native python extension module.

python3

image = cv.imread("someimage.jpg", 1)
dims = image.shape
image = image.ravel()
cppextenionmodule.np_to_mat(dims, image)

c++

static PyObject *np_to_mat(PyObject *self, PyObject *args){
    PyObject *size;
    PyArrayObject *image;

    if (!PyArg_ParseTuple(args, "O!O!", &PyTuple_Type, &size, &PyArray_Type, &image)) {
        return NULL;
    }
    int rows = PyLong_AsLong(PyTuple_GetItem(size ,0));
    int cols = PyLong_AsLong(PyTuple_GetItem(size ,1));
    int nchannels = PyLong_AsLong(PyTuple_GetItem(size ,2));
    char my_arr[rows * nchannels * cols];

    for(size_t length = 0; length<(rows * nchannels * cols); length++){
        my_arr[length] = (*(char *)PyArray_GETPTR1(image, length));
    }

    cv::Mat my_img = cv::Mat(cv::Size(cols, rows), CV_8UC3, &my_arr);

    ...
}

you can check the boost python wrapper solution link

read more about extension module link

read more about numpy via python extension module link

Martin Brisiak
  • 3,872
  • 12
  • 37
  • 51