如何在使用opencv和python抓取帧时保持恒定的FPS?

如何在使用opencv和python抓取帧时保持恒定的FPS?,python,opencv,webcam,video-capture,webcam-capture,Python,Opencv,Webcam,Video Capture,Webcam Capture,我使用OpenCV4和Python3打开一个网络摄像头,抓取帧并在窗口中显示它们,就像提供的第一个代码教程一样。但是,抓取不同的帧需要不同的时间:有时需要0.01秒抓取,有时需要0.33秒,这会在窗口中显示帧时产生延迟 是否有办法在抓取帧时强制执行固定时间,以便我可以无延迟地查看视频?我认为OpenCV就是这样,因为当我使用默认的windows摄像头查看器查看视频时,它会正常显示 我已经尝试过使用time.sleep()等待一段时间,然后再抓取帧。但这没有帮助 import numpy as n

我使用OpenCV4和Python3打开一个网络摄像头,抓取帧并在窗口中显示它们,就像提供的第一个代码教程一样。但是,抓取不同的帧需要不同的时间:有时需要0.01秒抓取,有时需要0.33秒,这会在窗口中显示帧时产生延迟

是否有办法在抓取帧时强制执行固定时间,以便我可以无延迟地查看视频?我认为OpenCV就是这样,因为当我使用默认的windows摄像头查看器查看视频时,它会正常显示

我已经尝试过使用
time.sleep()
等待一段时间,然后再抓取帧。但这没有帮助

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

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

    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

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

一种可能的方法是在循环中设置时间戳,并跟踪显示最后一帧的时间。例如,只有经过一定时间后,才显示帧。同时,不断读取帧以保持缓冲区为空,以确保具有最新的帧。您不想使用
time.sleep()
,因为它将冻结程序,而不会使缓冲区保持为空。一旦时间戳命中,您将显示帧并重置时间戳

import cv2
import time

cap = cv2.VideoCapture(0)

# Timeout to display frames in seconds
# FPS = 1/TIMEOUT 
# So 1/.025 = 40 FPS
TIMEOUT = .025
old_timestamp = time.time()

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

    if (time.time() - old_timestamp) > TIMEOUT:
        # Display the resulting frame
        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        old_timestamp = time.time()

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

我最近偶然发现了这个问题。我没有使用OpenCV的帧捕获,而是设置了一个单独的过程——使用ffmpeg捕获帧并将其写入ramdisk

Python的看门狗使我能够获得更新通知并启动OCR过程


事实证明,在控制捕获时,速度更快、效率更高,粒度更大。

如果工作正常,此应用程序将在read()调用时暂停,直到流媒体网络摄像头的下一帧可用。平滑显示取决于能否在不到1/FPS的时间内执行添加到循环中的任何内容。这还取决于摄像机是否符合UVC,也可能取决于编码算法是否符合MJPEG,这是大多数网络摄像机的情况。然而,您看到的延迟高达1/3秒的事实令人好奇,因为这是mpeg或其他帧间编码器的典型GOP周期


如果上述任何一项都不适用于您的案例,那么我怀疑问题与平台相关,而不是OCV问题。您是否尝试在另一个系统上复制该问题?

我认为没有任何方法可以实现您所描述的。你能把视频录下来然后处理吗?不幸的是我不能录视频。我需要用户实时查看网络摄像头的视频。您能详细解释一下您提出的解决方案吗?你有Python的看门狗的示例代码吗?非常感谢。