我在OSX(10.10.5)的python中使用OpenCV。我是OpenCV的新手。现在我只是想找到视频中某个事件发生的帧号。我正在使用轨迹栏浏览视频。
我遇到的问题是OpenCV报告的是非整数帧数。我的程序应该将帧编号设置为轨迹栏位置。轨迹栏位置始终为整数,但帧编号不是。视频时间越长,问题似乎越严重:视频越短,帧号(如果不是整数)就像253.99999999999994,当轨迹栏位置为254.但是,对于视频越长,帧编号越来越偏离整数值(例如,当轨迹栏位置为11212时为11212.20588235294;或者当轨迹栏位置为26631时为26631.529411764703。)请注意,这些数字并不总是舍入或截断为与轨迹栏位置相同的整数。
每个视频的总帧数也不是一个整数:1547.9999999999998用于我测试过的较短视频,而92651.38235294117用于我测试的长视频。较短的视频是.mov文件,较长的视频是.mp4,我使用ffmpeg从.mpg转码。
为什么会这样?我怎样才能算出帧数?谢谢你的帮助!这是我一直在使用的测试代码(注意它是基于http://giusedroid.blogspot.com/2015/05/python-opencv-frame-grabber.html的帧抓取器):
import numpy as np
import cv2
video_path = '#set video path here'
# grab a VideoCapture object
cap = cv2.VideoCapture(video_path)
#set some shorthand names
current_frame_flag = cv2.cv.CV_CAP_PROP_POS_FRAMES
total_frames_flag = cv2.cv.CV_CAP_PROP_FRAME_COUNT
win_name = "Frameshift calculator"
pos_trackbar='pos_trackbar'
cv2.namedWindow(win_name)
def seek_callback(x):
# we want to change the value of the frame variable globally
global frame
# by getting the position of the trackbar
i = cv2.getTrackbarPos(pos_trackbar, win_name)
# and skipping to the selected frame
cap.set(current_frame_flag, i)
_, frame = cap.read()
# and then update the window
cv2.imshow(win_name, frame)
#print out the current frame flag and the trackbar position
print(cap.get(current_frame_flag), i)
cv2.createTrackbar(pos_trackbar, win_name, 0, int(cap.get(total_frames_flag)), seek_callback)
while True:
# shows the image
cv2.imshow(win_name, frame)
# waits for keystroke
if cv2.waitKey(0) & 0xFF == ord('q'):
break
key = cv2.waitKey(0)
cap.release
cv2.destroyAllWindows()
一些样本(帧号,轨迹栏位置)对:
缩短视频(.mov): (1.0,0) (171.99999999999997,172) (842.9999999999999,843) (1141.0,1141) (1330.0,1330) (111.99999999999999,112) (235.99999999999997,236) (590.9999999999999,591) (1546.9999999999998,1547)
更长的视频(.mp4): (1.0,0) (6642.911764705882,6642) (27496.11764705882,27449) (49707.529411764706,49707) (64786.294117647056,64786) (84065.38235294117,84065)
答案 0 :(得分:2)
这很可能是因为您的帧速率不是整数。对于每个视频,请调查视频的实际帧速率:
frame_rate = cv2.cv.CV_CAP_PROP_FPS
事实上,对于某些视频,存在浮点帧速率。通常在电视中...至少在北美标准中,预期帧速率为30 FPS。但是,您很可能会有29.97 FPS。本文更详细地解释了这一点:http://theautomaticfilmmaker.com/blog/2009/2/23/about-frame-rates-or-why-2997.html。
然而,如果我可以总结一下,早在20世纪70年代,在先进的电子设备处理这个之前,在将颜色引入电视之前,广播确实以30 FPS进行,但由于发送颜色信息所需的额外信息,信息实际上干扰了声音信息,所以他们不得不将FPS延迟0.03 FPS来补偿和移动声音信息和颜色信息略有异相。
除了这一点之外,还有。您为一个视频获取另一个视频的浮点帧数的原因完全取决于帧速率。因此,通过尝试将帧编号放在所需位置,可能会出现所需的帧编号与视频中的实际帧不完全一致的情况,因此它会为您提供帧编号由于浮点帧速率以及你获得浮点结果的原因,它最终会对应。
当您开始使帧索引变大时,也存在漂移的原因仅仅是因为帧速率。当您开始指定更高的帧编号时,请记住,对于30 / 29.97场景的情况,您希望抓取索引的帧是您想要的,但因为每30 FPS,您将落后于0.03,对于较大的帧索引,这种差异会加剧,因为你每30帧的差异为0.03。
在获取确切的帧数方面,我在这里没有真正的建议。但是,您可以在所需的设置帧索引之前和之后提取一帧,然后从那里查看事物。指定实际的帧索引本身(至少从我所看到的)很少在实践中使用,并且出于这个原因的确切原因。