在 Python 中更快地传输图像 Numpy 数组

Transmit The Images Numpy Array Faster in Python

目前,我已经使用 Flask 框架开发了一个简单的 Web 应用程序。我使用的主要语言是 Python.

我假设我有 2 个主要文件,即 Flask Server 和 Flask Client。

Flask 服务器将初始化深度学习模型(例如对象检测)。

Flask 客户端将从相机源抓取帧并将帧发送到 Flask 服务器以获取对象的边界框。

我的问题是视频帧是否太大(4k 分辨率)。传输帧将花费很多时间。只有一帧的时间是 200 毫秒。

我想在客户端做一个实时应用。有没有人知道将帧从这个 Python 应用程序传递到另一个 Python 应用程序的好方法?我只考虑本地网络(在同一台计算机上)发生的进展。

Python 3.8 正好适合您 - Shared Memory。您可以创建一块共享内存并从同一台机器上的独立 Python 进程访问它。我做了一个非常简单的示例,其中包含在 2 个独立的 Python 进程之间共享的单帧 4k UHD 视频 (3840x2160)。因此,在一个终端中启动这个 (shmemA.py),最好在 IPython:

#!/usr/bin/env python3

import numpy as np
from multiprocessing import shared_memory

# Define dimensions of 4k video
w, h = 3840, 2160

# Create a named SharedMemory object
shm = shared_memory.SharedMemory(create=True, name="SharedVideoBuffer", size=w*h*3)

# Create a Numpy array backed by that SharedMemory
im = np.ndarray((h,w,3), dtype=np.uint8, buffer=shm.buf)

# Fill that array such that the other process can see it
im[:] = 32

然后在单独的终端中启动此 (shmemB.py):

#!/usr/bin/env python3

import numpy as np
from multiprocessing import shared_memory

# Define dimensions of 4k video
w, h = 3840, 2160

# Attach to existing SharedMemory created by our buddy
existing_shm = shared_memory.SharedMemory(name='SharedVideoBuffer')

# Create Numpy array backed by that SharedMemory
im = np.ndarray((h,w,3), dtype=np.uint8, buffer=existing_shm.buf)

您现在可以计算从第一个进程写入第二个进程需要多长时间:

%timeit im[:]=56
776 µs ± 20.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

而且你可以看到在进程之间传输一个4K帧需要776微秒,所以它可以达到1000多帧/秒。

在您的场景中,您可能会考虑在两个缓冲区之间设置 double-buffering(即 ping-ponging),以便一个进程写入第二个而另一个进程读取第一个。因此,您将创建 2 个共享内存缓冲区(或一个两倍大小的缓冲区)并在它们之间交替。您可以在两个进程之间使用 multiprocessing Queue 来告诉 reader 哪个缓冲区刚刚被填充。

关键字:Python,共享内存,SharedMemory,快速IPC,ping-pong,double-buffered,快速图像传输。