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

在Python中更快地传输图像Numpy数组,python,flask,image-processing,deep-learning,streaming,Python,Flask,Image Processing,Deep Learning,Streaming,目前,我已经使用Flask框架开发了一个简单的Web应用程序。我使用的主要语言是Python 我假设我有两个主文件,分别是Flask服务器和Flask客户端 Flask服务器将初始化深度学习模型(例如对象检测) Flask客户端将从相机源抓取帧,并将帧发送到Flask服务器以获取对象的边界框 我这里的问题是视频帧是否太大(4k分辨率)。传输帧需要很多时间。仅一帧的时间为200毫秒 我想在客户端制作一个实时应用程序。有人知道将帧从这个Python应用程序传递到另一个Python应用程序的好方法吗?

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

我假设我有两个主文件,分别是Flask服务器和Flask客户端

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

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

我这里的问题是视频帧是否太大(4k分辨率)。传输帧需要很多时间。仅一帧的时间为200毫秒


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

< P> Python 3.8对你来说完全正确。您可以创建一块共享内存,并从同一台机器上的独立Python进程访问它。我制作了一个非常简单的示例,在两个单独的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 fps以上

在您的场景中,您可以考虑两个缓冲区之间的双缓冲(即ping ping),以便一个进程正在写入第二个进程,而另一个进程正在读取第一个进程。因此,您将创建两个共享内存缓冲区(或一个大小为两倍的共享内存缓冲区),并在它们之间交替使用。您可以在两个进程之间使用一个

多处理队列
,告诉读取器哪个缓冲区刚刚被填满


关键词:Python、共享内存、共享内存、快速IPC、乒乓球、双缓冲、快速图像传输。

是的,非常感谢您的解决方案。我发现另一种可以应用的方法是Python中的内存映射文件。内存映射文件背后的想法非常简单。首先,我们定义一个虚拟文件,将文件的大小设置为在帧上相同。进程A(Python文件A)将从视频源读取帧并写入该文件。进程B(另一个文件B)将转到该文件在内存中的位置并读取字节。整个过程在20毫秒以上。我认为你的解决方案是我见过的最快的。对于4k视频来说,1000 FPS的速度是如此令人印象深刻。顺便说一句,多处理队列与从队列导入队列类似吗?我认为当我们在同一个文件中工作时,这些队列会很有用?如果在单独的Python文件中创建两个队列,则会将其视为两个不同的对象。如果我错了,请纠正我。先谢谢你@Mark SetchellI认为您必须从一个公共父进程启动两个进程,才能在它们之间发送multiprocessing.queue消息。如果我错了,请有人批评我。因此,您可能会在它们之间使用套接字(或SYSV、zeromq或MQTT消息)进行协调。