来自机器人通过 UDP 发送的图像在服务器 (PC) 上的实时视频流

Posted

技术标签:

【中文标题】来自机器人通过 UDP 发送的图像在服务器 (PC) 上的实时视频流【英文标题】:Live video stream on server (PC) from images sent by robot through UDP 【发布时间】:2011-05-01 10:12:49 【问题描述】:

嗯。我发现这似乎很有希望:

http://sourceforge.net/projects/mjpg-streamer/


好的。我将尝试清楚而详细地解释我正在尝试做的事情。

我有一个带摄像头和 wifi 棒的小型人形机器人 (this is the robot)。机器人的wifi棒平均wifi传输速率为1769KB/s。该机器人有 500Mhz CPU 和 256MB RAM,因此不足以进行任何严肃的计算(此外,机器人上已经运行了几个模块,用于运动、视觉、声纳、语音等)。

我有一台可以控制机器人的电脑。我正在尝试让机器人在房间里四处走动,并观看机器人在 PC 中看到的实时流视频。

我已经有工作了。机器人正在按照我的意愿行走并用相机拍照。图像正在通过 UDP 协议发送到我接收它们的 PC(我已通过将传入的图像保存在磁盘上来验证这一点)。

相机返回 YUV442 颜色空间中 640 x 480 像素的图像。我正在使用有损压缩 (JPEG) 发送图像,因为我试图在 PC 上获得最佳的 FPS。我正在使用 PIL 库在机器人上对 JPEG 进行压缩。

我的问题:

    有人能给我一些关于如何将传入的 JPEG 图像转换为实时视频流的想法吗?我知道我需要一些视频编码器。您推荐哪种视频编码器? FFMPEG 还是别的什么?我对视频流非常陌生,所以我想知道什么最适合这项任务。我更喜欢使用 Python 来编写这个,所以我更喜欢一些具有 Python API 的视频编码器或库。但我想如果这个库有一些好的命令行 API,它就不必在 Python 中。

    我能从中获得的最佳 FPS 是什么?鉴于 1769KB/s 的平均 wifi 传输速率和图像的尺寸?我应该使用与 JPEG 不同的压缩方式吗?

    我很乐意看到任何代码示例。链接到解释如何做到这一点的文章也可以。

一些代码示例。这是我如何将 JPEG 图像从机器人发送到 PC(缩短简化的 sn-p)。这在机器人上运行:

# lots of code here

UDPSock = socket(AF_INET,SOCK_DGRAM)

  while 1:
    image = camProxy.getImageLocal(nameId)
    size = (image[0], image[1])
    data = image[6]
    im = Image.fromstring("YCbCr", size, data)
    s = StringIO.StringIO()
    im.save(s, "JPEG")

    UDPSock.sendto(s.getvalue(), addr)

    camProxy.releaseImage(nameId)

  UDPSock.close()

  # lots of code here

这是我在 PC 上接收图像的方式。这在 PC 上运行:

  # lots of code here

  UDPSock = socket(AF_INET,SOCK_DGRAM)
  UDPSock.bind(addr)

  while 1:
    data, addr = UDPSock.recvfrom(buf)
    # here I need to create a stream from the data
    # which contains JPEG image

  UDPSock.close()

  # lots of code here

【问题讨论】:

相机本身没有返回 JPEG,某些编解码器中有一个视频流已经编码。必须有其他代码从该流中提取单个帧,是吗?如果是这样,那么您是否可以专注于从相机获取原始流并将其发送出去?我怀疑您将拥有足够的带宽。 @Brad 相机返回未经任何压缩的原始二进制图像。如果我将它们转换为 JPEG,它们会小得多。这样可以节省带宽,不是吗? @Brad 这是一个未经我压缩/更改的相机原始输出示例:richardknop.com/log.txt 啊,如果您要直接获取原始图像,而不是视频流,那么是的,您将通过发送 JPEG 节省大量带宽。但是,您可以通过发送视频流来节省更多带宽,这又回到了您的问题。抱歉,我不知道用 Python 实现编解码器的方法。 【参考方案1】:

查看您的第一个问题。尽管这里的解决方案使用了一组非流式图片。它可能会有所帮助。该示例使用 pyMedia。

http://pymedia.org/tut/src/make_video.py.html

一些符合你想要的。

http://code.google.com/p/mjpeg-stream-client/

如果您需要编辑二进制流:

http://bitbucket.org/haypo/hachoir/wiki/hachoir-parser

【讨论】:

pymedia 的最新版本是在 2006 年,看起来它已经好几年没有维护了。我会远离它。我会看看其他链接。【参考方案2】:

尝试pyffmpeg 并测试每个可用的编解码器以获得最佳性能。您可能需要一个非常轻量级的编解码器,例如 Smoke 或低调 H263 或 x264,并且您可能需要将分辨率降低到 320x240。

您需要在视频编码和解码的延迟与使用的带宽之间进行权衡,您可能会发现使用原始数据包降至 160x120 以进行快速场景分析,并且仅定期传输完整帧。您还可以将原始、低延迟、低分辨率、高更新 Feed 与高压缩、高延迟、高分辨率、低更新 Feed 混合使用。

【讨论】:

以上是关于来自机器人通过 UDP 发送的图像在服务器 (PC) 上的实时视频流的主要内容,如果未能解决你的问题,请参考以下文章

Java:通过 TCP 发送/接收数据并从 UDP 接收图像

终端通过GPRS发送UDP数据到固定IP:端口号,socket recvfrom接收不到数据,但却有返回值,如何解决

fpga实现udp功能思路---发送

如何在 Python 中通过 HTTP 提供来自 UDP 流的数据?

网吧局域网内机器发送udp数据包问题

无法将备份发送到 NAT 后的内部 PC