将 ffmpeg 流传递给 OpenCV

问题描述

我想使用重定向运算符将流从 ffmpeg 带到 cv2,以便我可以识别或标记流上的人脸,并再次重定向此流,使其在另一个流下运行。

一个没有facedetect,一个withfacedetect。

raspivid -w 1920 -h 1080 -fps 30 -o - -t 0 -vf -hf -b 6000000 | ffmpeg -f h264 -i - -vcodec copy -g 50 -strict experimental -f tee -map 0:v "[f=flv]rtmp://xx.xx.xx.xx/live/withoutfacedetect |[f=h264]pipe:1" > test.mp4

然后我阅读了 CV2 并看到了这篇文章

https://www.bogotobogo.com/python/OpenCV_Python/python_opencv3_Image_Object_Detection_Face_Detection_Haar_Cascade_Classifiers.php

然后我用我的照片运行脚本,非常惊讶我的脸周围有一个正方形。

但现在回到正题。这样做的最佳方法是什么?

感谢@Mark Setchell,忘记提及我使用的是 RaspBerry Pi 4。

解决方法

我仍然不能 100% 确定您真正想要做什么,并且有比我在评论中无法表达的更多想法。我还没有尝试过我认为你正在尝试做的所有事情,我可能想多了,但是如果我放下我的想法,也许其他人会添加一些有用的想法/更正......

好的,视频流最初是作为 RGB 或 YUV 从摄像头进入 Raspberry Pi 的。当 AFAIK、OpenCV 无法轻松解码时,使用 ffmpeg 将其编码为 h264,然后将其传递给 stdin 上的 OpenCV 似乎很愚蠢回到 BGR 或任何它自然喜欢用来进行人脸检测的东西。

所以,我想我会将参数更改为 raspivid 以便它生成 RGB 数据帧,并删除所有 h264 比特率内容,即

raspivid -rf rgb  -w 1920 -h 1080 -fps 30 -o - | ffmpeg ...

现在我们有 RGB 进入 ffmpeg,因此您需要使用类似于您已经拥有的 teemap 并将 RGB 发送到 OpenCV 在它的 stdin 和 h264 编码第二个流为 rtmp,就像你已经拥有的那样。

然后在 OpenCV 中,您只需要从 read() 的 1920x1080x3 字节中执行 stdin 以获得每个帧。框架将采用 RGB,但您可以使用:

cv2.cvtColor(cv2.COLOR_RGB2BGR)

按照 OpenCV 的要求将频道重新排序为 BGR。

当您从 stdin 读取数据时,您需要执行以下操作:

frame = sys.stdin.buffer.read(1920*1080*3)

而不是:

frame = sys.stdin.read(1920*1080*3)

对图像等二进制数据进行处理。