服务器(PC)上的实时视频流来自机器人通过 UDP 发送的图像
唔。我发现这似乎很有希望:
http://sourceforge.net/projects/mjpg-streamer/
好的。我将尝试清楚、详细地解释我正在尝试做的事情。
我有一个带有摄像头和 wifi 棒的小型人形机器人(这是机器人) 。机器人的 WiFi 棒平均 WiFi 传输速率为 1769KB/s。该机器人拥有 500Mhz CPU 和 256MB RAM,因此不足以进行任何严肃的计算(此外,机器人上已经运行了几个用于运动、视觉、声纳、语音等的模块)。
我有一台电脑,可以用来控制机器人。我试图让机器人在房间里走动,并观看机器人在电脑中看到的实时流视频。
我已经在工作了。机器人按照我希望的方式行走并用相机拍照。图像通过 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(缩短的简化片段)。它在机器人上运行:
# 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
Hmm. I found this which seems promising:
http://sourceforge.net/projects/mjpg-streamer/
Ok. I will try to explain what I am trying to do clearly and in much detail.
I have a small humanoid robot with camera and wifi stick (this is the robot). The robot's wifi stick average wifi transfer rate is 1769KB/s. The robot has 500Mhz CPU and 256MB RAM so it is not enough for any serious computations (moreover there are already couple modules running on the robot for motion, vision, sonar, speech etc).
I have a PC from which I control the robot. I am trying to have the robot walk around the room and see a live stream video of what the robot sees in the PC.
What I already have working. The robot is walking as I want him to do and taking images with the camera. The images are being sent through UDP protocol to the PC where I am receiving them (I have verified this by saving the incoming images on the disk).
The camera returns images which are 640 x 480 px in YUV442 colorspace. I am sending the images with lossy compression (JPEG) because I am trying to get the best possible FPS on the PC. I am doing the compression to JPEG on the robot with PIL library.
My questions:
Could somebody please give me some ideas about how to convert the incoming JPEG images to a live video stream? I understand that I will need some video encoder for that. Which video encoder do you recommend? FFMPEG or something else? I am very new to video streaming so I want to know what is best for this task. I'd prefer to use Python to write this so I would prefer some video encoder or library which has Python API. But I guess if the library has some good command line API it doesn't have to be in Python.
What is the best FPS I could get out from this? Given the 1769KB/s average wifi transfer rate and the dimensions of the images? Should I use different compression than JPEG?
I will be happy to see any code examples. Links to articles explaining how to do this would be fine, too.
Some code samples. Here is how I am sending JPEG images from robot to the PC (shortened simplified snippet). This runs on the robot:
# 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
Here is how I am receiving the images on the PC. This runs on the 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
检查你的第一个问题。尽管这里的解决方案使用非流式图片集。这可能有帮助。该示例使用 pyMedia。
有些符合你想要的。
如果您需要编辑二进制流:
Checking out your first question. Though the solution here uses a non-streaming set of pictures. It might help. The example uses pyMedia.
Some along the lines of what you want.
If you have a need to edit a binary stream:
尝试 pyffmpeg 并测试每个可用的编解码器以获得最佳性能。您可能需要一个非常轻量级的编解码器,例如 Smoke 或低调的 H263 或 x264,并且您可能需要将分辨率降至 320x240。
您需要在视频编码和解码的延迟与所使用的带宽之间进行权衡,您可能会发现原始数据包的分辨率降至 160x120,以便进行快速场景分析,并且仅定期传输全帧。您还可以将原始、低延迟、低分辨率、高更新源与高压缩、高延迟、高分辨率、低更新源混合。
Try pyffmpeg and test each available codec for the best performance. You probably need a very lightweight codec like Smoke or low profile H263 or x264, and you probably need to drop the resolution to 320x240.
You have a trade off between latency of the video encoding and decoding and the bandwidth used, you might find dropping down to 160x120 with raw packets for a quick scene analysis and only periodically transmitting a full frame. You could also mix a raw, low latency, low resolution, high update feed with a high compressed, high latency, high resolution, low update feed.