>问题大纲
我在 Process1 中捕获了一个 h264 实时视频流(我称之为">流"(。我的目标是从流中提取每个帧,并使用 Process2 使用 OpenCV 对其进行分析。(Process1 是 nodejs,Process2 是 Python(
我尝试过的事情,以及它们的失败模式:
- 通过命名的 fifo 管道将流从一个进程 1 直接发送到进程 2:
我成功地将流从进程 1 定向到管道中。但是,在Process2(这是Python(中,我无法(a(从流中提取单个帧,并且(b(将从h264中提取的任何数据转换为OpenCV格式(例如.JPEG numpy数组(。
我曾希望使用OpenCV的VideoCapture((方法,但它不允许你将FIFO管道作为输入传递。我能够通过将 h264 流保存到 .h264 文件,然后将其作为文件路径传递来使用 VideoCapture。这对我没有帮助,因为我需要实时进行分析(即,在将流读入OpenCV之前,我无法将流保存到文件中(。
- 将流从进程 1 传送到 FFMPEG,使用 FFMPEG 将流格式从 h264 更改为 MJPEG,然后将输出通过管道传输到进程 2:
我尝试使用以下命令执行此操作:
猫管从过程1.fifo | ffmpeg -i 管道:0 -f h264 -f mjpeg 管道:1 | cat> pipeToProcess2.fifo
这种方法的最大问题是FFMPEG从进程1获取输入,直到进程1被杀死,然后进程2才开始接收数据。
此外,在 Process2 方面,我仍然不明白如何从通过管道的数据中提取单个帧。我打开管道进行读取(作为"f"(,然后执行数据 = f.readline((。数据的大小变化很大(有些读取的长度约为 100,其他读取的长度约为 1,000(。当我使用 f.read(( 而不是 f.readline(( 时,长度要大得多,大约 100,000。
如果我知道我得到了正确大小的数据块,我仍然不知道如何将其转换为与OpenCV兼容的数组,因为我不了解它的格式。这是一个字符串,但是当我打印出来时,它看起来像这样:
_M~0A0 tQ,\% e f/H #Y p f# Kus } F ra G +$x %V }[ Wo 1'̶A c * &=Z^ o' T۽ SX-TƑV&H| $~
从 base64 转换似乎没有帮助。我也试过:
array = np.fromstring(data, dtype=np.uint8)
它确实转换为数组,但不是基于我尝试解码的帧的 640x368x3 尺寸有意义的大小。
- 使用百老汇等解码器.js转换 h264 流:
这些似乎专注于流式传输到网站,而我试图将它们重新用于我的目标并没有成功。
澄清我不想做什么:
我发现了许多有关将 h264 视频流式传输到网站的相关问题。这是一个已解决的问题,但没有一个解决方案可以帮助我提取单个帧并将它们放入与 OpenCV 兼容的格式中。
此外,我需要连续实时使用提取的帧。因此,将每一帧另存为.jpg没有帮助。
系统规格
树莓派 3 运行树莓派杰西
其他详细信息
我试图概括我在问题中遇到的问题。如果知道有用的话,Process1 正在使用 node-bebop 包从 Parrot Bebop 2.0 中拉下 h264 流(使用 drone.getVideoStream(((。我尝试使用通过node-bebop(getMjpegStream(((提供的其他视频流。这奏效了,但几乎不是实时的;我得到的数据流非常间歇性。我已经在 node-bebop 存储库中将该特定问题作为问题输入。
感谢您的阅读;我真的很感谢任何人能给予的任何帮助!
通过设置以下环境变量,我能够解决在 Python 中使用 OpenCV(使用 FFMPEG 构建(打开 Parrot Anafi 流的问题:
export OPENCV_FFMPEG_CAPTURE_OPTIONS="rtsp_transport;udp"
FFMPEG 默认为 TCP 传输,但来自无人机的馈送是 UDP,因此这会为 FFMPEG 设置正确的模式。
然后使用:
cv2.VideoCapture(<stream URI>, cv2.CAP_FFMPEG)
ret, frame = cap.read()
while ret:
cv2.imshow('frame', frame)
# do other processing on frame...
ret, frame = cap.read()
if (cv2.waitKey(1) & 0xFF == ord('q')):
break
cap.release()
cv2.destroyAllWindows()
照常。
这也适用于鹦鹉Bebop,但我没有一个可以测试它。
网上有一些建议,可以使用标准将h264流输送到opencv程序中:
some-h264-stream | ./opencv-program
其中 OpenCV-Program 包含以下内容:
VideoCapture cap("/dev/stdin");