如何最有效地将连续的帧流发送到服务器
How to send continuous stream of frames to server most efficiently
我正在尝试将帧从本地摄像头(raspberry pi 摄像头,但也可能是我笔记本电脑的网络摄像头)发送到我 运行 所在的 Google 云实例帧的AI处理。
我正在设法通过 http(即 tcp??)发送通过 opencv 捕获的帧,并在 flask 服务器上接收它们。当 flask 服务器在本地 运行 时,我可以获得良好的 fps(图像大小为 640x480 时 50+ fps),但是一旦我将帧发送到 google 实例上的 flask 应用程序,fps 就会急剧下降到 ~ 5fps.
我目前发送帧的方式:
while True:
frame = vs.read() #Separate thread, using cv2 to get the frame
ret, jpeg = cv2.imencode('.jpg', frame)
imgdata = jpeg.tobytes()
response = requests.post(
url='http://<IP address of google instance>:<port>',
data= imgdata,
headers={'content-type':'image/jpeg'},
)
我发现这有两个问题:
1 - 使用 tcp 意味着我比 udp 协议慢,但是 udp 的字节大小有限。如果我错了请纠正我,但是发送截断的帧并将它们放回服务器上似乎非常复杂。
2 - 即使我有 udp 工作,也没有帧压缩,所以我永远不会达到有效的传输
我希望答案类似于使用 ffmpeg,但到目前为止我只弄清楚了如何使用 ffmpeg 在本地端口上流式传输帧,我不知道是否可以将帧发送到远程服务器。
有什么关于最佳前进方向的建议吗?
您的案例的正确协议选择是 TCP。 UDP 不保证数据会以正确的顺序到达并且完好无损。在您的情况下,UDP 不会比 TCP 快(如果您确保数据完好无损并且在您的代码中按顺序排列)。
您已经通过将图像转换为 jpg 来压缩图像。额外的压缩效率真的很低。 TCP和UDP在传输中都不压缩数据。
我相信现在您在某种程度上受到 requests
库和将数据编码为 HTTP 协议的限制。您应该考虑使用没有 HTTP 开销的纯 TCP。这可以通过标准 python 库中的 socket
模块来完成。但是你可能仍然会有低性能,因为你没有帧间压缩并且只使用帧内压缩。您需要考虑使用 ffmpeg 压缩来自相机的数据,并使用您的程序或使用 ffmpeg's point 2 point streaming.
通过 TCP 发送流
我正在尝试将帧从本地摄像头(raspberry pi 摄像头,但也可能是我笔记本电脑的网络摄像头)发送到我 运行 所在的 Google 云实例帧的AI处理。
我正在设法通过 http(即 tcp??)发送通过 opencv 捕获的帧,并在 flask 服务器上接收它们。当 flask 服务器在本地 运行 时,我可以获得良好的 fps(图像大小为 640x480 时 50+ fps),但是一旦我将帧发送到 google 实例上的 flask 应用程序,fps 就会急剧下降到 ~ 5fps.
我目前发送帧的方式:
while True:
frame = vs.read() #Separate thread, using cv2 to get the frame
ret, jpeg = cv2.imencode('.jpg', frame)
imgdata = jpeg.tobytes()
response = requests.post(
url='http://<IP address of google instance>:<port>',
data= imgdata,
headers={'content-type':'image/jpeg'},
)
我发现这有两个问题: 1 - 使用 tcp 意味着我比 udp 协议慢,但是 udp 的字节大小有限。如果我错了请纠正我,但是发送截断的帧并将它们放回服务器上似乎非常复杂。 2 - 即使我有 udp 工作,也没有帧压缩,所以我永远不会达到有效的传输
我希望答案类似于使用 ffmpeg,但到目前为止我只弄清楚了如何使用 ffmpeg 在本地端口上流式传输帧,我不知道是否可以将帧发送到远程服务器。
有什么关于最佳前进方向的建议吗?
您的案例的正确协议选择是 TCP。 UDP 不保证数据会以正确的顺序到达并且完好无损。在您的情况下,UDP 不会比 TCP 快(如果您确保数据完好无损并且在您的代码中按顺序排列)。
您已经通过将图像转换为 jpg 来压缩图像。额外的压缩效率真的很低。 TCP和UDP在传输中都不压缩数据。
我相信现在您在某种程度上受到 requests
库和将数据编码为 HTTP 协议的限制。您应该考虑使用没有 HTTP 开销的纯 TCP。这可以通过标准 python 库中的 socket
模块来完成。但是你可能仍然会有低性能,因为你没有帧间压缩并且只使用帧内压缩。您需要考虑使用 ffmpeg 压缩来自相机的数据,并使用您的程序或使用 ffmpeg's point 2 point streaming.