如何使用Open CV模块通过Python知道文件(.avi)中帧的总数。
如果可能的话,我们可以通过它获得视频文件的所有信息(分辨率,fps,持续时间等)。
Answers:
使用较新的OpenCV版本(我使用3.1.0)时,其工作方式如下:
import cv2
cap = cv2.VideoCapture("video.mp4")
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print( length )
与其他视频属性类似 cv2.CAP_PROP_*
import cv2
cap = cv2.VideoCapture(fn)
if not cap.isOpened():
print "could not open :",fn
return
length = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
width = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.cv.CV_CAP_PROP_FPS)
有关更多信息,请参见此处。
而且,所有这些都带有一粒盐,并不是所有这些道具都是强制性的,有些可能在您的捕获/视频编解码器中不可用
这是它与Python 3.6.5(在Anaconda上)和OpenCV 3.4.2一起工作的方式。[注意]:对于OpenCV官方网站上提供的任何属性,您需要从“ CV_CAP_PROP_xx”中删除“ CV_” 。
import cv2
cap = cv2.VideoCapture("video.mp4")
property_id = int(cv2.CAP_PROP_FRAME_COUNT)
length = int(cv2.VideoCapture.get(cap, property_id))
print( length )
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
有两种方法可以确定视频文件中的帧数
方法1速度很快,并且依赖于OpenCV的视频属性功能,该功能几乎可以瞬间确定视频文件中的帧数。但是,由于它取决于您的OpenCV和视频编解码器版本,因此需要进行精度折衷。另一方面,手动计数每个帧的准确率将达到100%,尽管会慢很多。这是一个默认情况下尝试执行方法1的函数,如果失败,它将自动利用方法2
def frame_count(video_path, manual=False):
def manual_count(handler):
frames = 0
while True:
status, frame = handler.read()
if not status:
break
frames += 1
return frames
cap = cv2.VideoCapture(video_path)
# Slow, inefficient but 100% accurate method
if manual:
frames = manual_count(cap)
# Fast, efficient but inaccurate method
else:
try:
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
except:
frames = manual_count(cap)
cap.release()
return frames
基准测试
if __name__ == '__main__':
import timeit
import cv2
start = timeit.default_timer()
print('frames:', frame_count('fedex.mp4', manual=False))
print(timeit.default_timer() - start, '(s)')
start = timeit.default_timer()
print('frames:', frame_count('fedex.mp4', manual=True))
print(timeit.default_timer() - start, '(s)')
方法1的结果
frames: 3671
0.018054921 (s)
方法2的结果
frames: 3521
9.447095287 (s)
请注意,这两种方法相差150帧,并且方法#2比方法#1慢得多。因此,如果您需要速度但又愿意牺牲精度,请使用方法1。如果您可以延迟但需要准确的帧数,请使用方法2
另一个不依赖有时会发生错误的CV_CAP_PROP
吸气剂的解决方案是循环遍历整个视频文件
收集有关分辨率的信息比较棘手,因为某些编解码器支持可变分辨率(类似于音频文件中的VBR,其中比特率不是恒定的,而是覆盖了一些预定义的范围)。
可以计算FPS,但是这里您遇到与分辨率相同的问题-常数(CFR)与变量(VFR)。这更多是一个多线程问题。我个人将使用帧计数器,该帧计数器在每个有效帧之后增加,而每隔1秒(在后台线程中运行),计时器将触发保存当前计数器的值,然后将其重置。您可以将值存储在列表中,以便在最后还知道视频具有的总帧数时计算平均/恒定帧速率。
这种相当简单的处理方式的缺点在于,您必须遍历整个文件,如果文件长达数小时,则肯定会引起用户注意。在这种情况下,您可以对此有所了解,并在后台过程中做到这一点,同时让您的应用程序在收集有关已加载视频文件的信息时让用户执行其他操作。
优点是,无论您拥有什么视频文件,只要OpenCV可以读取它,您都将获得非常准确的结果,CV_CAP_PROP
这与您预期的效果可能不一样。