OpenCV 库(在 Python 中)的 VideoCapture 方法是处理每一帧,还是在进行大量处理时也跳过帧?

Does the VideoCapture method of the OpenCV library (in Python) process every frame, or does it also skip frames when doing hefty processing?

我正在使用 Python 中的 OpenCV 库来读取实时视频帧,以便在每个帧中跟踪多个对象。

我使用 VideoCapture 方法执行此操作,代码如下所示:

vid = cv2.VideoCapture()

# Loop over all frames
while True:

    ok, frame = vid.read()
    if not ok:
       break

    # Quite heavy computations

所以我得到每个 while 循环,VideoCapture 调用 read() 方法来处理一帧。但是,我想知道在处理这个帧的过程中会发生什么?我的猜测是在此处理过程中跳过了一些帧。这是真的还是帧被添加到缓冲区并且它们最终都按顺序处理?

假设您没有从文件中读取,相机的帧将被添加到预定义大小的缓冲区中。您可以通过

访问它
cv2.get(cv2.CAP_PROP_BUFFERSIZE)

并设置为

cv2.set(cv2.CAP_PROP_BUFFERSIZE, my_size)

缓冲区填满后,将跳过新的帧。

即使 VideoCapture 有一个缓冲区来存储图像,在繁重的过程中,您的循环 也会跳过一些帧 。按照标准,您的 VideoCaptureProperties 具有 属性 CAP_PROP_BUFFERSIZE = 38,这意味着它将存储 38 帧。从缓冲区读取下一帧的 read() method uses grab() 方法。

大家可以自己测试一下,下面是一个简单的例子,用延时来模拟一个繁重的过程。

import numpy as np
import cv2
import time
cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame',gray)

    # Introduce a delay to simulate heavy process
    time.sleep(1) 
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

您会看到图像跳帧(并且不会产生我们在慢速图像序列中预期的 "slow-motion" 效果)。因此,如果你的过程足够快,你可以匹配相机的 FPS。