我想用我的多子,但分享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)
共享阵列仅包含视频的第一帧。 我怎样才能正确地写入到共享阵列能够读取子进程中每一帧? 我不想使用队列或管道。 共享内存是去怎么把多个进程会消耗掉帧的方式。
有几个问题,一个是共享数组的大小和形状,另一个是你如何访问它。 为了解决第一个问题,首先需要确保创建数组的大小相当于一个视频帧的大小。 您已经阅读框,并使用其宽度和高度(虽然你可以不用阅读任何帧 ),但没有考虑它的通道数。
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