将structre从Python传递到C ++或将numpy数组而不是文件地址传递给Yolo

时间:2018-12-11 20:20:19

标签: python c++ data-structures yolo

我正在尝试将内存中的图像传递给Yolo,而不是文件地址。

source code中,它使用openCV读取图像。由于openCV返回c格式的mat格式,因此它将使用mat_to_image(mat im)函数将mat格式转换为图像格式。 但是python中的opencv使用numpy.ndarray,所以我不能使用mat_to_image()

因此,我尝试按照我们拥有的作者代码here将自己的numpy数组放入图像格式:

class IMAGE(ctypes.Structure):
_fields_ = [("w", ctypes.c_int),
            ("h", ctypes.c_int),
            ("c", ctypes.c_int),
            ("data", ctypes.POINTER(ctypes.c_float))]

这是我所拥有的:

import darknet as dn

im = cv2.imdecode(in-memory_bytelike_object, cv2.IMREAD_COLOR)
h,w,c = im.shape
my_image = IMAGE()
my_image.w = ctypes.c_int(w)
my_image.h = ctypes.c_int(h)
my_image.c = ctypes.c_int(c)
my_image.data = im.ctypes.data_as(ctypes.POINTER(ctypes.c_float))

print(dn.detect(net, meta, my_image))

我还以这种方式更改了detect函数:

def detect(net, meta, image, thresh=.5, hier_thresh=.5, nms=.45):
    # im = load_image(image, 0, 0)  //image_address->mat (using cv2)-> image (using mat_to_image) and return image 
    im = image
    ...

但是当我运行它时,出现此错误:

ArgumentError: argument 2: <class 'TypeError'>: expected IMAGE instance instead of IMAGE

我想问题是我没有以正确的方式传递数据结构,但是我不确定。

我阅读了一些其他有关在Python和C ++之间传递数据结构的答案,但是我认为应该有一个更简单的解决方案。

1 个答案:

答案 0 :(得分:0)

我设法用这种方式做到了:

以下是将numpy数组转换为图像格式的方法:

import darknet as dn
def array_to_image(arr):
    arr = arr.transpose(2,0,1)
    c = arr.shape[0]
    h = arr.shape[1]
    w = arr.shape[2]
    arr = (arr/255.0).flatten()
    data = dn.c_array(dn.c_float, arr)
    im = dn.IMAGE(w,h,c,data)
    return im

使用问题中提到的detect函数的修改版本。

所以它是这样的:

im = cv2.imdecode(in-memory_bytelike_object, cv2.IMREAD_COLOR)
im = array_to_image(arr)
dn.rgbgr_image(im)
print(dn.detect(net, meta, im))

got the function from here