共享的OpenCV视频帧作为多处理过程之间numpy的阵列正确的方式(Right way to sh

2019-10-29 07:42发布

我想用我的多子,但分享OpenVC我捕捉到的帧video_capture.read()创建一个新的对象,并在犯规写信给我说我要多多用它包裹分享numpy的阵列multiprocessing.Array()

下面是代码:

ret, frame = video_capture.read()
shared_array = mp.Array(ctypes.c_uint16, frame.shape[0] * frame.shape[1], lock=False)
while True:
    b = np.frombuffer(shared_array)
    ret, b = video_capture.read()

但缓冲区b得到由覆盖read()函数。 所以我不写我的缓存/共享阵列。

在子我做以下操作:

img = np.frombuffer(shared_array)
cv2.imshow('Video', img)

共享阵列仅包含视频的第一帧。 我怎样才能正确地写入到共享阵列能够读取子进程中每一帧? 我不想使用队列或管道。 共享内存是去怎么把多个进程会消耗掉帧的方式。

Answer 1:

有几个问题,一个是共享数组的大小和形状,另一个是你如何访问它。 为了解决第一个问题,首先需要确保创建数组的大小相当于一个视频帧的大小。 您已经阅读框,并使用其宽度和高度(虽然你可以不用阅读任何帧 ),但没有考虑它的通道数。

ret, frame = video_capture.read()
shape = frame.shape
shared_array = mp.Array(ctypes.c_uint16, shape[0] * shape[1] * shape[2], lock=False)

你选择uint16的数据类型,这是很好的(同样,你可以使用video_capture.get(cv2.CAP_PROP_FORMAT)来获得帧的确切数据类型,但你可以选择任何你想要的,因为与NumPy将值转换为阵列数据类型)。 然而,当你创建NumPy的数组,你必须指定要使用的数据类型,否则会使用float64默认情况下:

b = np.frombuffer(shared_array, dtype=np.uint16)

然后你必须重塑它有一个框架的形状(不,这不会创建一个新的NumPy的阵列,它只是一个视图,所以它仍然采用共享缓存):

b = b.reshape(shape)

最后,当你阅读框,你不希望覆盖b变量,而是写入阵列。 此外,你应该只有这样做,当一帧实际阅读:

while True:
    ret, frame = video_capture.read()
    if ret:
        b[:] = frame


文章来源: Right way to share opencv video frame as Numpy array between multiprocessing processes