I try to convert a opencv3 cv::Mat image in C++ to a Numpy array in python by using ctypes. The C++ side is a shared library that is reading the image from a shared memory region. The shared memory is working and is not relevant to this question.
extern "C" {
unsigned char* read_data() {
shd_mem_offset = region->get_address() + sizeof(sFrameHeader);
unsigned char *frame_data = (unsigned char *) shd_mem_offset;
return frame_data;
}
sFrameHeader *read_header() {
sFrameHeader *frame_header;
void *shd_mem_offset = region->get_address();
frame_header = (sFrameHeader*)(shd_mem_offset);
return frame_header;
}
}
There are two functions declared as visible for ctypes. One is returning the cv::Mat attributes like cols, rows and step. The other fucntion returning the cv::Mat data (mat.data).
The python side looks like this:
import ctypes
import numpy as np
from numpy.ctypeslib import ndpointer
class sFrameHeader(ctypes.Structure):
_fields_ = [
("frame_size", ctypes.c_size_t),
("frame_mat_rows", ctypes.c_int),
("frame_mat_cols", ctypes.c_int),
("frame_mat_type", ctypes.c_int),
("frame_mat_step", ctypes.c_size_t)]
Lib = ctypes.cdll.LoadLibrary('interface.so')
Lib.read_header.restype = ctypes.POINTER(sFrameHeader)
header = deepva_module_interface.read_header()
frame_size = header.contents.frame_size
frame_mat_rows = header.contents.frame_mat_rows
frame_mat_cols = header.contents.frame_mat_cols
frame_mat_step = header.contents.frame_mat_step
frame_mat_type = header.contents.frame_mat_type
Lib.read_data.restype = ndpointer(dtype=ctypes.c_char, shape=(frame_size,))
data = Lib.read_data()
I want to display the image in python then...
cv2.imshow('image', data)
cv2.waitKey(0)
cv2.destroyAllWindows()
..but i think the shape of the numpy array is wrong. How can i correctly build the numpy array to be able to use it as OpenCV image in python?
Are there any solutions for converting it to numpy? There are boost::python converters like here. I use Boost for shared memory but would like to stay with ctypes for the C binding stuff.