如何在python中知道cv2文件中Frame的总数

Nir*_*raj 54 python video opencv frame-rate frame

如何使用open cv模块通过Python知道文件(.avi)中Frame的总数.

如果可能的话,我们可以通过这个获得视频文件的所有信息(分辨率,fps,持续时间等).

phe*_*ev8 80

使用较新的OpenCV版本(我使用3.1.0),它的工作原理如下:

import cv2

cap = cv2.VideoCapture("video.mp4")
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print( length )
Run Code Online (Sandbox Code Playgroud)

和其他视频属性类似 cv2.CAP_PROP_*

  • 'module'对象没有属性'CAP_PROP_FRAME_COUNT' (2认同)

ber*_*rak 36

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)
Run Code Online (Sandbox Code Playgroud)

请看这里了解更多信息.

此外,所有这些都带有一点盐,并非所有这些道具都是强制性的,有些可能不适用于您的捕获/视频编解码器


nat*_*ncy 13

有两种方法可以确定视频文件中的帧数

  • 方法#1:利用内置的OpenCV属性访问视频文件元信息,快速高效但不准确
  • 方法#2:使用计数器手动循环视频文件中的每一帧,该计数器缓慢且低效但准确

方法 #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
Run Code Online (Sandbox Code Playgroud)

基准

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)')
Run Code Online (Sandbox Code Playgroud)

方法 #1 结果

frames: 3671
0.018054921 (s)
Run Code Online (Sandbox Code Playgroud)

方法#2 结果

frames: 3521
9.447095287 (s)
Run Code Online (Sandbox Code Playgroud)

请注意,这两种方法相差 150 帧,并且方法 #2 比方法 #1 慢得多。因此,如果您需要速度但愿意牺牲准确性,请使用方法 #1。在您可以接受延迟但需要确切帧数的情况下,请使用方法 #2


MGL*_*don 11

以下是它如何与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 )
Run Code Online (Sandbox Code Playgroud)

  • 这很棒!您还可以使用`length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))`检索 (2认同)

rba*_*dar 5

另一个不依赖于有时有问题的CV_CAP_PROPgetter 的解决方案是循环遍历整个视频文件

  • 每次遇到有效帧时增加帧计数器变量,并在无效帧出现时停止(视频文件结尾)。
  • 收集有关分辨率的信息比较棘手,因为一些编解码器支持可变分辨率(类似于音频文件中的 VBR,其中比特率不是常数而是覆盖一些预定义的范围)。

    • 恒定分辨率- 在这种情况下,您只需要第一帧来确定整个视频文件的分辨率,因此不需要遍历整个视频
    • 可变分辨率- 您需要获取每一帧(宽度和高度)的分辨率并计算平均值以获得视频的平均分辨率
  • 可以计算FPS,但是在这里您遇到与分辨率相同的问题 - 常数 (CFR) 与变量 (VFR)。这更像是一个多线程问题。就我个人而言,我会使用一个帧计数器,它会在每个有效帧之后增加,而计时器(在后台线程中运行)会以 1 秒的间隔触发保存当前计数器的值,然后将其重置。您可以将这些值存储在列表中,以便在最后计算平均/恒定帧速率,同时您还将知道视频的总帧数。

这种相当简单的做事方式的缺点是您必须遍历整个文件,如果它长达几个小时,用户肯定会注意到。在这种情况下,您可以聪明一点,在后台进程中执行此操作,同时让用户在您的应用程序收集有关已加载视频文件的信息时执行其他操作。

优点是,无论您拥有什么视频文件,只要 OpenCV 可以从中读取,您都会获得非常准确的结果,CV_CAP_PROP这与您期望的结果可能会或可能不会工作不同。