获取视频中每个帧的时间戳 [英] Getting timestamp of each frame in a video

查看:3805
本文介绍了获取视频中每个帧的时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

不幸的是,每个视频具有不同的帧速率(范围从20到30).使用OpenCV,我可以获取每个视频的帧率:

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

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

这很好用,从理论上讲,我可以为视频中的每一帧添加1000/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.

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

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

推荐答案

您要cv2.CAP_PROP_POS_MSEC.在此处中查看

实际上,正如 DanMašek向我指出的那样,当您购买该物业时,看起来OpenCV是正是这样计算(至少假设您使用的是FFMPEG):

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

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

因此,您似乎总是要依赖恒定帧速率的假设.但是,即使假设帧速率恒定,也要乘以帧号,而不仅仅是继续添加1000/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:

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))

第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

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

这当然以毫秒为单位,所以也许看起来并不大.但是在这里,我的计算时间几乎减少了1毫秒,而这仅适用于11秒钟的视频.而且无论如何,使用此属性会更容易.

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.

这篇关于获取视频中每个帧的时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆