目前我正在使用2017_08_31_0121.mp4一个 21 秒长的视频作为我的视频,一旦我将其分解为帧,我会得到 504 帧。这意味着每秒帧数设置为 24。我想更改帧数,但我不知道以下代码的哪一部分负责设置每秒帧数。
问题:
我想了很长一段时间,默认 FPS 是 25,但现在我有 24,你能告诉我默认 FPS 在哪里设置以及它是什么吗?
如果我想使用自定义 FPS(假设为 10),我该如何修改以下代码来做到这一点?
import cv2
vidcap = cv2.VideoCapture('/content/2017_08_31_0121.mp4')
success, image = vidcap.read()
count = 0
while success:
if count<10:
id = f'00{count}'
elif count < 100:
id = f'0{count}'
else:
id = count
cv2.imwrite(f"./new_frames/frame{id}.jpg", image) # save frame as JPEG file
success, image = vidcap.read()
count += 1
Run Code Online (Sandbox Code Playgroud)
您需要了解“视频”的工作原理。
视频由关键帧和 P/B 帧组成。关键帧本身就是完整的图像。为了解码 P/B 帧,需要首先解码前面的帧。某些视频文件仅包含关键帧(“帧内”)。某些视频文件每约 0.1-10 秒包含一个关键帧,其间仅包含 P/B 帧。
您可以在视频中跳转,但只能直接跳至关键帧。如果您想跳到非关键帧,则必须先跳到前面的关键帧,然后解码后面的每个帧,直到到达目的地。
我建议您不要遵循的想法:
ffmpeg -i INPUT -r 3 OUTPUT将读取整个视频,并根据需要复制/丢弃帧以达到每秒 3 帧,同时保持您在视频中看到的“速度”。它还必须对结果重新编码。如果您需要以该帧速率重复读取同一视频,那么这只是一个明智的选择。
将GNU Parallel与 ffmpeg结合起来是没有意义的,因为 ffmpeg 本身使用所有可用的 CPU 并行运行其解码和编码(对于大多数编解码器)。
您可以执行以下操作:
使用VideoCapture 的方法grab和方法retrieve。grab反复打电话。这对解码帧和推进视频做了最少的工作。致电retrieve索要您真正想要的框架。这将完成其余的工作,并且它将为您提供该框架作为数组。
您必须fps使用检查视频的价值vidcap.get(cv.CAP_PROP_FPS),然后计算并决定是否只需要抓取,或者同时抓取和检索。
import numpy as np
import cv2 as cv
vidcap = cv2.VideoCapture('/content/2017_08_31_0121.mp4')
assert vidcap.isOpened()
fps_in = vidcap.get(cv.CAP_PROP_FPS)
fps_out = 3
index_in = -1
index_out = -1
while True:
success = vidcap.grab()
if not success: break
index_in += 1
out_due = int(index_in / fps_in * fps_out)
if out_due > index_out:
success, frame = vidcap.retrieve()
if not success: break
index_out += 1
# do something with `frame`
Run Code Online (Sandbox Code Playgroud)