【问题标题】:Efficient way of sending a large number of images from client to server将大量图像从客户端发送到服务器的有效方法
【发布时间】:2019-02-13 10:02:40
【问题描述】:

我正在做一个项目,其中一个客户需要从相机拍摄几张快照(即它实际上是在拍摄一段短时视频,因此是一串帧),然后 将所有图像发送到服务器 然后对这些图像执行一些处理并将结果返回给客户端。

客户端和服务器都在运行Python3代码。

关键部分是图片发送。

首先是一些背景,图像是 *640*480 jpeg* 文件。 JPEG 被选为默认选项,但也可以选择质量较低的编码。它们由相机按顺序捕获。因此,我们有大约 ~600 帧 需要发送。帧大小约为 110KiB。

客户端由 Raspberry Pi 3 型号 B+ 组成。它通过 wifi 将帧发送到 5c 服务器。对于原型版本,服务器和客户端都驻留在同一个 LAN 中。但在连接介质(有线或无线)和区域(LAN 或城域)方面,未来的部署可能会有所不同。

我已经为此实施了几种解决方案:

  1. 在服务器和客户端上使用 Python 套接字:我要么在捕获一帧后直接发送 一帧,要么发送 在整个流捕获完成后按顺序排列所有图像

  2. 使用 Gstreamer:我正在客户端上启动 GStreamer 端点,并在流式传输时直接将帧发送到服务器。我正在使用 GStreamer 支持编译的 OpenCV 在服务器端捕获流,然后将它们保存到磁盘。

现在,我面临的问题是,即使两种解决方案都“运行良好”(它们完成了“最终”工作,即向服务器发送数据并接收基于远程处理的结果),我相信有更好的方法可以使用 Python 套接字库或任何其他可用工具将大量数据发送到服务器。

所有的个人研究都是在这件事上完成的,这使我找到了类似于我的解决方案,使用 Python 套接字,或者脱离了上下文(依赖于纯 Python 以外的其他后端)。

通过更好的方式,我假设:

  1. 尽可能节省带宽的解决方案。
  2. 尽快发送所有数据的解决方案。

对于 1. 我稍微修改了我的第一个解决方案,将所有捕获的帧存档并压缩到一个 .tgz 文件中,然后发送到服务器。它确实减少了带宽使用,但也增加了两端花费的时间(由于解压缩过程)。当数据集很大时,显然尤其如此。

对于 2. GStreamer 允许我在服务器上捕获和接收之间的延迟可以忽略不计。然而,我根本没有压缩,由于上述原因,我不能真正使用这个库进行进一步的开发。

如何在 Python 中以最小的带宽使用和延迟将大量图像从一台客户端发送到一台服务器?

【问题讨论】:

  • 您使用的是 Raspberry Pi 还是超级计算机?您是通过 wifi 还是有线以太网发送?您的 JPEG 文件有多大(以字节为单位)?你能接受质量较低的 JPEG 编码吗?
  • 谢谢。我在原始帖子中添加了其他信息。
  • 您目前是否正在利用您的 Raspberry Pi 有 4 个内核这一事实?我通常发现我可以通过让一个核心/线程尽可能快地单独进行采集,然后运行 ​​1-3 个核心/线程进行处理/传输,从而获得良好的性能。还可以考虑运行两个并行线程,通过套接字将图像发送到远程机器,这样您就可以使用完整的 wifi 带宽。
  • 确实是很好的建议。我没有使用 4 个内核,所以理论上我可以用一个进行采集,然后在两个不同的内核上分拆两个进程以进行帧发送(偶数/不均匀帧)。如果我一次处理一帧,这将非常有用,但就我而言,我可以等待首先发送完整的帧序列。保留对未来项目的建议。

标签: python image sockets opencv gstreamer


【解决方案1】:

如果您想将图像作为帧传输,您可以使用一些现有的应用程序,例如 MJPEG-Streamer,它将来自网络摄像头接口的图像编码为 JPG,从而减小图像大小。但是,如果您需要更强大的高级编码传输,您可以使用一些 Linux 工具,例如 FFMPEGhere 中记录的流式传输。

如果您想要较低的实现并通过您的代码控制整个流进行修改,您可以使用基于 Web 的框架,如 Flask 并直接传输您的图像抛出 HTTP 协议。你可以在here找到一个很好的例子。

如果您不想流式传输,您可以将整组图像转换为视频编码格式,如h264,然后传输字节抛出网络。您可以使用opencv 来执行此操作。 还有一些用python编写的好的库,比如pyffmpeg

【讨论】:

  • MJPEG-Streamer 是一个独立的应用程序,据我从文档中得知,我想避免在解决方案中使用外部程序。同样对于 Flask,即使 lib 是纯 Python,在堆栈中添加另一个协议 (http) 对我来说看起来有点矫枉过正(个人意见,我很确定它会很好地实现目标)。 Pyffmpeg 看起来很有希望,但似乎该项目已经很久没有维护了。但是,使用 h264 将帧与 opencv 合并似乎是我的完美选择。谢谢!
【解决方案2】:

您可以通过网络使用 ffmpeg 重新流式传输相机,以便客户端可以双向读取它。这将减少延迟。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 1970-01-01
相关资源
最近更新 更多