我已经使用我编写的Android 5.2应用程序从平板电脑的前置摄像头录制了几个视频。我已经为每个视频存储了以毫秒(Unix时间)为单位的开始时间戳。
不幸的是,每个视频都有不同的帧速率(范围从20到30)。使用OpenCV,我能够获得每个视频的帧速率:
import cv2
video = cv2.VideoCapture(videoFile)
fps = video.get(cv2.CAP_PROP_FPS)
这很好用,理论上我只需为视频中的每一帧添加1000 / fps(由于毫秒)。但这假设帧率在整个录制过程中保持稳定。我不知道是不是这样。
Python中是否有可能获取视频中每帧的时间戳(以毫秒为单位),而与帧速率无关?
答案 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 代码)