使用FFmpeg将AVI视频按已知帧率分割成帧

29

这段内容是从相关帖子的评论中获取的。但是,它们似乎没有被注意到 =(

我已经使用过

ffmpeg -i myfile.avi -f image2 image-%05d.bmp

myfile.avi分割成以.bmp格式存储的帧。看起来它似乎可以工作,但并不完全正确。录制视频时,我以1000fps的速率录制,视频的长度为 2min29sec。如果我的计算是正确的,整个视频应该有149,000帧。然而,当我运行时:

ffmpeg -i myfile.avi -f image2 image-%05d.bmp

我只得到了4472个文件。如何获得原始的149k帧?

我还尝试将我的原始AVI的帧率转换为1000fps,方法是

ffmpeg -i myfile.avi -r 1000 otherfile.avi

但这似乎并没有解决我的问题。

5个回答

43
ffmpeg -i myfile.avi -r 1000 -f image2 image-%07d.png

我不确定输出150k个bmp文件是否是一个好主意。也许png足够了?


这对我从笔相机录制的视频有效。 - user3137329
使用“-r 1000”将强制FFmpeg简单地复制(或如果输入fps更高,则丢弃帧)帧以达到1000。这可能不是您想要的。 - llogan

12

你的数学部分没问题,2分钟29秒约为149秒。以1000 fps计算,这将产生149000帧。然而,你的输出文件名仅有5个数字位置,而149000帧需要6个数字位置,因此尝试使用“image-%06d.bmp”格式。

接下来是磁盘大小的问题:你的图像是否适合磁盘?对于BMP格式,每个图像都使用自己的大小。你可以尝试使用JPEG图片,它们的压缩比大约为10倍。

另一个想法是:如果ffmpeg没有找到(合理的)帧速率,它会降至每秒25或30帧。你可能需要指定它。在源和目标上都应如此操作,请查看man页面(unix系统中使用“man ffmpeg”命令):

   To force the frame rate of the input file (valid for raw formats
   only) to 1 fps and the frame rate of the output file to 24 fps:
           ffmpeg -r 1 -i input.m2v -r 24 output.avi

就我个人而言:我使用 ffmpeg -y -i "video.mpg" -sameq "video.%04d.jpg" 将视频拆分成图片。-sameq是为了强制jpeg以合理的质量输出,-y是为了避免询问是否覆盖旧文件。对于你:

ffmpeg -y -r 1000 -i "myfile.avi" -sameq "image.%06d.jpg"


-sameq现已弃用。 - Dylan Madisetti

0
使用FFMPEG时,我只得到了大约33k个文件,但如果你使用Python,你可以使用这段代码,它会为一个23分钟、29.97FPS的视频生成正确的41k个文件。
import cv2
import os
import sys

###------------------------------------------------------------------------ ###
    
def vid_split():
    
    print("Splitting videos to images(.jpg) at the videos frames per second.",
          "\n", "For example at 30 FPS, you'll get 30 images for every second of video.", "\n")
    
    videoFile = "./Path/To/Video.mp4"
    cap = cv2.VideoCapture(videoFile)
    frameRate = cap.get(cv2.CAP_PROP_FPS)
    pic_num = 0
    framenum = 0
    maxframe = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret == False:
            break
        framenum += 1

        print(f"\rProcessing: {framenum} of {maxframe}",end="")
        sys.stdout.flush()

        # zfill puts the number of zeros before framenum, if framenum is 1
        # filename would be frame00000001.jpg
        filename = "tmp_frames/frame{}.jpg".format(str(framenum).zfill(8))

        if os.path.exists(filename):
            pass
        else:
            cv2.imwrite(str(filename), frame)
        pic_num += 1

    print(f"\r                                                                                          ",end="")

    cap.release()
    cv2.destroyAllWindows()
    print("[*] Completed Video Operations! ", "\n")
    
vid_split()

0

我认为这里有一个误解:HS视频系统的输出帧率不太可能达到1000 fps,而是比较正常的30(或50/60)fps。除了会使大多数视频播放器超负荷以外,以与录制时相同的速度显示序列也会适得其反。

基本上,1000 fps输入的1秒钟在输出的30 fps下大约相当于33秒钟。

这个场景的持续时间确实是2分29秒(在正常速率下结果是约82分钟的视频),还是大约需要4.5秒钟(4472帧),这在正常播放中是2分29秒?


0

我在Ubuntu 18.04终端上尝试过这个。

ffmpeg -i input_video.avi output_frame_path_images%5d.png

其中,

-i = 输入


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接