获取视频中每个帧的时间戳

时间:2017-12-10 20:42:50

标签: python opencv video frame-rate

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

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

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

这很好用,理论上我只需为视频中的每一帧添加1000 / fps(由于毫秒)。但这假设帧率在整个录制过程中保持稳定。我不知道是不是这样。

Python中是否有可能获取视频中每帧的时间戳(以毫秒为单位),而与帧速率无关?

2 个答案:

答案 0 :(得分:10)

你想要cv2.CAP_PROP_POS_MSEC。查看所有不同的捕获属性here

编辑:实际上,正如Dan Mašek指出的那样,当你抓住那个属性时,看起来OpenCV是exactly doing that calculation(至少假设你正在使用FFMPEG):

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

所以看起来你总是依赖于恒定的帧率假设。但是,即使假设帧速率恒定,重要的是乘以帧数而不仅仅是继续添加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))
  

第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

这当然是毫秒,所以也许它看起来不那么大。但是在这里,我在计算中差不多1毫秒,这只是一个11秒的视频。无论如何,使用这个属性更容易。

答案 1 :(得分:0)

通常这些相机有一个滚动快门,这意味着图像是逐行扫描的,所以严格地说,不能在图像上放置一个时间戳。我一直在使用精确定时(ns 级)的 LED 闪光灯同步多个卷帘快门相机(iPhone 6)。我发现帧率是可变的(高速时标称 240 fps,但在 239,something 和 241,something 之间变化。相互同步最多可以完成 1/500000 s,但这需要特殊设置。如果你有兴趣我可以给你发一些文档(恐怕我的软件是用 Matlab 编写的,所以没有现成的 python 代码)