我正试图从本地相机(树莓派相机,但也可能是我的笔记本电脑的网络摄像头)发送帧到谷歌云实例,我正在运行帧的AI处理。
我正在设法通过http(即tcp ??)发送通过opencv捕获的帧,并在烧瓶服务器上接收它们。当烧瓶服务器在本地运行时,我可以获得良好的fps(图像大小为640x480的50+ fps),但是一旦我将帧发送到谷歌实例上的烧瓶应用程序,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协议。您应该考虑使用纯TCP,而不需要HTTP的开销。这可以通过标准python库中的socket
模块完成。但是,您可能仍然会有低性能,因为您没有帧间压缩并且只使用帧内压缩。您需要考虑使用ffmpeg来压缩相机中的数据,并使用您的程序或使用ffmpeg's point 2 point streaming通过TCP发送数据流。