将视频转换为帧图像序列

apt*_*sox 5 video-processing gstreamer

我需要使用网络摄像头捕获视频并为捕获的每个视频帧输出单个图像。

我曾尝试将 gstreamer 与 multifilesink 一起使用,例如:

gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"
Run Code Online (Sandbox Code Playgroud)

但是,这实际上并没有输出每一帧,这意味着如果我以 30 fps 的速度录制 2 秒,我不会得到 60 张图像。我假设这是因为编码不能那么快,所以我需要另一种方法。

我认为如果我有一个管道捕获视频,并且一个单独的管道将该视频转换为帧,它可能会起作用,但我对编解码器了解得不够多。我是否需要将视频编码为 h264 或 mp4 之类的文件才能再次解码?

有没有人有任何想法或建议?请记住,我需要能够在代码中执行此操作,而不是使用 Adob​​e Premiere 等应用程序。

谢谢!

Hav*_*aff 5

您可以简单地在其中添加一个队列,如下所示:

gst-launch v4l2src device=/dev/video1 ! video/x-raw-yuv,framerate=30/1 ! queue ! ffmpegcolorspace ! pngenc ! multifilesink location="frame%d.png"
Run Code Online (Sandbox Code Playgroud)

这应该确保允许视频捕获以 30 fps 运行,然后将其写入磁盘可以按照自己的节奏进行。请注意,如果您离开此设置时间过长,队列将增长到相当大的大小。


mre*_*hub 1

我必须提供的解决方案不使用 gstreamer 而是使用 ffmpeg。我希望这对你来说也很好。

正如此论坛帖子中所述,您可以使用如下内容:

ffmpeg -i movie.avi frame%d.png
Run Code Online (Sandbox Code Playgroud)

获取视频每一帧的 png/jpg 图像。
但根据您使用的输入文件,您可能必须在运行 ffmpeg 之前将其转换为 MPEG vid。

注意:
如果您希望图像文件名中包含前导零,请改用%05d(对于 5 位数字,如 C 中的printf()):

ffmpeg -i movie.avi frame%05d.png
Run Code Online (Sandbox Code Playgroud)

输出文件格式取决于文件扩展名,因此您可以使用.jpg, .bmp, ... 而不是.png.