将 ffmpeg 流传递给 OpenCV

Pass ffmpeg Stream to OpenCV

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

一个没有面部检测,一个有面部检测。

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% 确定您真正想做什么,而且我的想法比我在评论中表达的要多。我还没有尝试过所有我认为你正在尝试做的事情,我可能想得太多了,但如果我放下我的思路,也许其他人会添加一些有用的东西 thoughts/corrections...

好的,视频流从相机进入 Raspberry Pi 最初是 RGB 或 YUV。使用 ffmpeg 将其编码为 h264,将其传递给 OpenCV 在其 stdin 上似乎很愚蠢,当 AFAIK,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中,你只需要从1920x1080x3字节的stdin做一个read()来获取每一帧。框架将采用 RGB,但您可以使用:

cv2.cvtColor(cv2.COLOR_RGB2BGR)

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

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

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

而不是:

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

破坏图像等二进制数据。