5

I am working on a project on which I have to deal with images between Python and C++. In order to send an image from C++ to Python, I send a pointer on the first pixel of my image (being a Mat object from OpenCV library) and in Python with two for loops I used this pointer to create a 2D numpy array.

But I don't succeed to do the same in the other way : get the memory address of the first pixel of the numpy 2D array (an image) and pass it to the C++.

Assume x is my image (2D numpy array), I tried solution like :

  • x.__array_interface__['data'][0] but this give an integer, not an address
  • x.data which give different values each time I call it because it gives me the address of a temporary buffer, not the image itself

Thank you in advance for any advice/help.

Mathieu Gauquelin
  • 601
  • 11
  • 35
  • What do you mean exactly by *"send an image between Python and C++"*? Are you using sockets, or message queues or some type of shared memory? – Mark Setchell Jun 27 '18 at 08:49
  • 1
    I want to read image in Python, and send it to C++ to perform operation on C++. So I have to find a way to do it, and I use a pointer for that. But I found the way to do it using #ralf answer. – Mathieu Gauquelin Jun 27 '18 at 08:52

2 Answers2

3

I found a "simple" way to do that:

In C++, the function has to take as argument a void * ptr, and like this I can create a Mat object using the pointer sent from Python :

void myCfunction(void* ptr){
    Mat matrix = Mat(sizes, CV_8UC1, (uchar*)ptr);
}

And, in Python, use __array_interface__ to get the memory address (in int type, weird) :

mydll.myFunction(myNumpyArray.__array_interface__['data'][0], ...)
Mathieu Gauquelin
  • 601
  • 11
  • 35
1

in how to get the memory address of a numpy array for C is also used __array_interface__, the integer that is returned is a pointer to the data segment of the array and no memory address :

data (optional)

A 2-tuple whose first argument is an integer (a long integer if necessary) that points to the data-area storing the array contents. This pointer must point to the first element of data (in other words any offset is always ignored in this case). The second entry in the tuple is a read-only flag (true means the data area is read-only).

This attribute can also be an object exposing the buffer interface which will be used to share the data. If this key is not present (or returns None), then memory sharing will be done through the buffer interface of the object itself. In this case, the offset key can be used to indicate the start of the buffer. A reference to the object exposing the array interface must be stored by the new object if the memory area is to be secured.

Default: None

source : https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html

you can see the content of the entire dictionary returned by __array_interface__ with print x.__array_interface__[]

__array_struct__ contains a distinct C pointer to the first element of the array, you can access it from within your C(++) code, example is in http://blog.audio-tk.com/2008/11/04/exposing-an-array-interface-with-swig-for-a-cc-structure/:

`

C-struct access

This approach to the array interface allows for faster access to an array using only one attribute lookup and a well-defined C-structure.

__array_struct__

A :c:type: PyCObject whose voidptr member contains a pointer to a filled PyArrayInterface structure. Memory for the structure is dynamically created and the PyCObject is also created with an appropriate destructor so the retriever of this attribute simply has to apply Py_DECREF to the object returned by this attribute when it is finished. Also, either the data needs to be copied out, or a reference to the object exposing this attribute must be held to ensure the data is not freed. Objects exposing the __array_struct__ interface must also not reallocate their memory if other objects are referencing them.

The PyArrayInterface structure is defined in numpy/ndarrayobject.h as:

typedef struct {
  int two;              /* contains the integer 2 -- simple sanity check */
  int nd;               /* number of dimensions */
  char typekind;        /* kind in array --- character code of typestr */
  int itemsize;         /* size of each element */
  int flags;            /* flags indicating how the data should be interpreted */
                        /*   must set ARR_HAS_DESCR bit to validate descr */
  Py_intptr_t *shape;   /* A length-nd array of shape information */
  Py_intptr_t *strides; /* A length-nd array of stride information */
  void *data;          --------> /* A pointer to the first element of the array */ < ------
  PyObject *descr;      /* NULL or data-description (same as descr key
                                of __array_interface__) -- must set ARR_HAS_DESCR
                                flag or this will be ignored. */
} PyArrayInterface;

source : https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.interface.html

ralf htp
  • 9,149
  • 4
  • 22
  • 34