OpenCV从实时网络摄像头流中获取帧速率和帧时间戳?

djmepvbi  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(198)

我正在努力尝试读取/设置我的网络摄像头的fps,并读取从网络摄像头捕获的特定帧的时间戳。特别是当我尝试使用vc.get(cv2.CAP_PROP_POS_MSEC)vc.get(cv2.CAP_PROP_FPS)vc.get(cv2.CAP_PROP_FRAME_COUNT)时,它们分别返回-1,0,-1。显然我错过了一些东西。有人能帮忙吗?代码看起来像这样:

import os
import time

import cv2
import numpy as np
[...]
# Create a new VideoCapture object
vc = cv2.VideoCapture(0, cv2.CAP_DSHOW)
vc.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
vc.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# Initialise variables to store current time difference as well as previous time call value
previous = time.time()
delta = 0
n = len(os.listdir("directory"))

# Keep looping
while True:
    timem = vc.get(cv2.CAP_PROP_POS_MSEC)
    fps = vc.get(cv2.CAP_PROP_FPS)
    total_frames = vc.get(cv2.CAP_PROP_FRAME_COUNT)

    print(timem, fps, total_frames)
    # Get the current time, increase delta and update the previous variable
    current = time.time()
    delta += current - previous
    previous = current

    # Check if 3 (or some other value) seconds passed
    if delta > 3:
        # Operations on image
        # Reset the time counter
        delta = 0

        _, img = vc.read()
        [...]
        # press esc to exit
    if cv2.waitKey(20) == 27:
        break

**edit:**如果我删除cv2.CAP_DSHOW,它可以工作,但我不能使用CAP_PROP_FRAME_WIDTH

jm2pwxwz

jm2pwxwz1#

显然,你的操作系统上的OpenCV后端(DSHOW)并不跟踪帧时间戳。
read()之后,只使用time.perf_counter()或一个兄弟函数。它将足够接近,除非你节流阅读,在这种情况下,帧将是陈旧的。
你可以在OpenCV的github上打开一个issue,并为DSHOW/MSMF请求这样的功能。人们会期望这样的时间戳代表帧被获取的时间,而不是用户程序最终读取的时间。

qfe3c7zg

qfe3c7zg2#

在网络摄像头上将cv2.VideoCapture对象与cv2.CAP_DSHOW后端配合使用时,您似乎遇到了获取帧时间戳(cv2.CAP_PROP_POS_MSEC)、每秒帧数(cv2.CAP_PROP_FPS)和帧数(cv2.CAP_PROP_FRAME_FPS)等属性的正确值的问题。
您遇到的问题可能与您正在使用的后端有关。使用cv2.CAP_DSHOW时,某些属性的行为可能与默认后端不同。下面是您的代码的修改版本,以尝试使您提到的属性工作:

import os
import time
import cv2

# Create a new VideoCapture object with CAP_DSHOW
vc = cv2.VideoCapture(0, cv2.CAP_DSHOW)

# Set the frame width and height
vc.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
vc.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# Check if the camera opened successfully
if not vc.isOpened():
    print("Error: Could not open the camera.")
    exit()

# Initialize variables to store current time difference as well as previous time call value
previous = time.time()
delta = 0

# Keep track of the number of frames processed
frame_count = 0

# Keep looping
while True:
    # Read a frame from the camera
    ret, frame = vc.read()

    if not ret:
        print("Error: Could not read frame.")
        break

    # Calculate and print frame timestamp, FPS, and frame count
    timem = vc.get(cv2.CAP_PROP_POS_MSEC)
    fps = vc.get(cv2.CAP_PROP_FPS)
    total_frames = vc.get(cv2.CAP_PROP_FRAME_COUNT)

    print(f"Timestamp: {timem} ms, FPS: {fps}, Frame Count: {total_frames}")

    # Get the current time, increase delta, and update the previous variable
    current = time.time()
    delta += current - previous
    previous = current

    # Check if 3 (or some other value) seconds passed
    if delta > 3:
        # Reset the time counter
        delta = 0
        frame_count += 1

        # Perform operations on the frame here

    # Display the frame
    cv2.imshow("Frame", frame)

    # Press 'q' to exit the loop
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the VideoCapture and close the OpenCV window
vc.release()
cv2.destroyAllWindows()

相关问题