How to maintain constant FPS when grabbing frames with opencv and python?

北城余情 提交于 2020-01-24 12:54:06

问题


I am using OpenCV4 along with python 3 to open a webcam, grab the frames and display them in a window, just like the first code tutorial provided here. However, it takes a different amount of time grabbing different frames: sometimes it takes 0.01 s to grab, and sometimes it takes 0.33 s, which creates lags when showing the frames in the window.

Is there a way to force a constant time when grabbing frames so that i can see the video without lag? I think it is happening with OpenCV because when i use a default windows camera viewer to see the video it displays it normally.

What i already tried is wait for some time using time.sleep() before grabbing a frame again. But this does not help.

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()

回答1:


One potential way is to set a timestamp within the loop and keep track of the time the last frame was shown. For instance, only once a certain amount of time has elapsed then you show the frame. At the same time, you constantly read frames to keep the buffer empty to ensure that you have the most recent frame. You don't want to use time.sleep() because it will freeze the program and not keep the buffer empty. Once the timestamp hits, you show the frame and reset the timestamp.

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()



回答2:


I stumbled on this problem recently. Instead of using OpenCV's frame capture, I set up a separate process - using ffmpeg to capture and write them to a ramdisk.

Python's watchdog enabled me to get notified of updates and kick off an OCR process.

Turned out to be faster and more efficient with a lot of granularity in controlling the capture.



来源:https://stackoverflow.com/questions/56759785/how-to-maintain-constant-fps-when-grabbing-frames-with-opencv-and-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!