如何最有效地将连续的帧流发送到服务器

时间:2019-04-27 08:03:30

标签: python opencv ffmpeg video-streaming

我试图将帧从本地相机(树莓派相机,但也可能是笔记本电脑的网络摄像头)发送到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在本地端口上传输帧,我不知道是否可以将帧发送到远程服务器。

关于最佳前进方式的任何建议吗?

1 个答案:

答案 0 :(得分:2)

适合您的情况的协议的正确选择是TCP。 UDP不保证数据将以正确的顺序到达并完整无缺。在您的情况下,UDP不会比TCP快(如果您确保数据完整且代码顺序正确)。

您已经通过将图像转换为jpg来压缩它们。额外的压缩实际上是效率低下的。 TCP和UDP都不会压缩传输中的数据。

我相信,目前您requests库在一定程度上限制了将数据编码为HTTP协议的工作。您应该考虑使用纯TCP,而没有HTTP的开销。这可以通过标准python库中的socket模块来完成。但是,由于您没有帧间压缩,而仅使用帧内压缩,因此您可能仍然会降低性能。您可能需要考虑使用ffmpeg压缩相机中的数据,并使用程序或使用ffmpeg's point 2 point streaming通过TCP发送流。