Python 获取视频中每一帧的时间戳

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47743246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:20:40  来源:igfitidea点击:

Getting timestamp of each frame in a video

pythonopencvvideoframe-rate

提问by machinery

I have recorded several videos from the front cam of my tablet with an Android 5.2 application I have written. I have stored the start timestamp in milliseconds (Unix time) for each video.

我已经使用我编写的 Android 5.2 应用程序从平板电脑的前置摄像头录制了几个视频。我以毫秒(Unix 时间)为单位存储了每个视频的开始时间戳。

Unfortunately each video has a different framerate (ranging from 20 to 30). With OpenCV I'm able to get the framerate for each video:

不幸的是,每个视频都有不同的帧率(从 20 到 30)。使用 OpenCV,我可以获得每个视频的帧率:

import cv2
video = cv2.VideoCapture(videoFile)
fps = video.get(cv2.CAP_PROP_FPS)

This works well and theoretically I could just add 1000/fps (due to milliseconds) for each frame in the video. But this assumes that the framerate remains stable throughout the whole recording. I don't know if this is the case.

这很有效,理论上我可以为视频中的每一帧添加 1000/fps(由于毫秒)。但这假设帧率在整个录制过程中保持稳定。我不知道是不是这种情况。

Is there a possibility in Python to get the timestamp (in milliseconds) of each frame in the video independent of the framerate?

Python 中是否有可能独立于帧率获取视频中每一帧的时间戳(以毫秒为单位)?

回答by alkasm

You want cv2.CAP_PROP_POS_MSEC. See all the different capture properties here.

你要cv2.CAP_PROP_POS_MSEC在此处查看所有不同的捕获属性。

Edit: Actually, as Dan Ma?ekpointed out to me, when you grab that property, it looks like OpenCV is exactly doing that calculation(at least assuming you're using FFMPEG):

编辑:实际上,正如Dan Ma?ek向我指出的那样,当您获取该属性时,OpenCV 似乎正在执行该计算(至少假设您使用的是 FFMPEG):

case CV_FFMPEG_CAP_PROP_POS_MSEC:
    return 1000.0*(double)frame_number/get_fps();

So it seems you're always going to rely on a constant frame rate assumption. However, even assuming a constant frame rate, it's important that you multiply by the frame number and not just keep adding 1000/fps. Errors will build up when you're repeatedly adding floats which, over a long video, can make a big difference. For example:

所以看起来你总是会依赖一个恒定的帧率假设。但是,即使假设帧速率恒定,重要的是乘以帧数而不是继续添加1000/fps. 当您反复添加浮点数时,错误就会累积,这在长视频中会产生很大的不同。例如:

import cv2

cap = cv2.VideoCapture('vancouver2.mp4')
fps = cap.get(cv2.CAP_PROP_FPS)

timestamps = [cap.get(cv2.CAP_PROP_POS_MSEC)]
calc_timestamps = [0.0]

while(cap.isOpened()):
    frame_exists, curr_frame = cap.read()
    if frame_exists:
        timestamps.append(cap.get(cv2.CAP_PROP_POS_MSEC))
        calc_timestamps.append(calc_timestamps[-1] + 1000/fps)
    else:
        break

cap.release()

for i, (ts, cts) in enumerate(zip(timestamps, calc_timestamps)):
    print('Frame %d difference:'%i, abs(ts - cts))

Frame 0 difference: 0.0
Frame 1 difference: 0.0
Frame 2 difference: 0.0
Frame 3 difference: 1.4210854715202004e-14
Frame 4 difference: 0.011111111111091532
Frame 5 difference: 0.011111111111091532
Frame 6 difference: 0.011111111111091532
Frame 7 difference: 0.011111111111119953
Frame 8 difference: 0.022222222222183063
Frame 9 difference: 0.022222222222183063
...
Frame 294 difference: 0.8111111111411446

第0帧差:0.0
1点差:0.0
2帧差:0.0
3帧差:1.4210854715202004e-14
帧4的区别:0.011111111111091532
框架5的区别:0.011111111111091532
框架6的区别:0.011111111111091532
框架7的区别:0.011111111111119953
框架8差:0.022222222222183063
帧9差异:0.022222222222183063
...
294帧差异:0.8111111111411446

This is of course in milliseconds, so maybe it doesn't seem that big. But here I'm almost 1ms off in the calculation, and this is just for an 11-second video. And anyways, using this property is just easier.

这当然是以毫秒为单位的,所以也许它看起来没有那么大。但在这里我在计算中几乎关闭了 1 毫秒,这仅适用于 11 秒的视频。无论如何,使用这个属性更容易。