python - 在多处理进程之间将opencv视频帧共享为Numpy数组的正确方法

标签 python numpy opencv shared-memory python-multiprocessing

我想与我的多处理子进程共享我在 OpenVC 中捕获的帧,但是 video_capture.read()创建一个新对象并且不写入我将通过用 multiprocessing.Array() 包装来共享的我的 numpy 数组

这是代码:

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()

但是缓冲区 bread() 覆盖功能。所以我不写入我的缓冲区/共享数组。

在子流程中,我执行以下操作:
img = np.frombuffer(shared_array)
cv2.imshow('Video', img)

共享数组仅包含视频的第一帧。如何正确写入共享数组以读取子进程中的每一帧?
我不想使用队列或管道。共享内存是一种方式,因为更多的进程会消耗帧。

最佳答案

有几个问题,一个是共享数组的大小和形状,另一个是您如何访问它。要解决第一个问题,首先需要确保创建的数组的大小与视频帧的大小相对应。您已经阅读了一个框架并使用了它的宽度和高度(尽管 you can do it without reading any frame ),但没有考虑它的 channel 数。

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)

然后你必须将它 reshape 为一个框架的形状(并不是说这不会创建一个新的 NumPy 数组,它只是一个 View ,所以它仍然使用共享缓冲区):
b = b.reshape(shape)

最后,当您读取帧时,您不想覆盖 b变量,而是写入数组。此外,您应该只在实际读取帧时才这样做:
while True:
    ret, frame = video_capture.read()
    if ret:
        b[:] = frame

关于python - 在多处理进程之间将opencv视频帧共享为Numpy数组的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49191615/

相关文章:

python - 嵌套的 json 到 csv - 通用方法

javascript - 插件如何增强 Anki 的 JavaScript?

python - 如何从文件夹(包括子文件夹)的图像创建 Numpy 数组

当提供 -w 参数时,python 2to3 不会更改 Huey 文件

python - 如何在 pandas 中按列名称连接列?

linux - 电视 (TV) 视频实时像素级分析的建议

python - Python 函数究竟是如何返回/产生对象的?

Python 3 虚拟环境 - 不存在的包

c++ - 在 FileStorage 中使用路径作为键

python - 矢量化照片 : Finding an Adapted Algorithm