изменить частоту кадров в opencv 3.4.2 - PullRequest
0 голосов
/ 29 августа 2018

Я хочу уменьшить количество кадров, получаемых в секунду в веб-камере, это код, который я использую

#!/usr/bin/env python

import cv2

cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FPS, 10)
fps = int(cap.get(5))
print("fps:", fps)

while(cap.isOpened()):

    ret,frame = cap.read()
    if not ret:
        break

    cv2.imshow('frame', frame)

    k = cv2.waitKey(1)
    if k == 27:
        break

Но это не вступает в силу, у меня все еще есть 30 кадров в секунду по умолчанию вместо 10, настроенных cap.set(cv2.CAP_PROP_FPS, 10). Я хочу уменьшить частоту кадров, потому что у меня есть детектор рук, который занимает достаточно много времени для обработки каждого кадра, я не могу сохранить кадры в буфере, поскольку он обнаружит руку в предыдущих позициях. Я мог запустить детектор, используя таймер или что-то еще, но я думал, что изменение fps было проще, но это не сработало, и я не знаю почему.

Я использую Opencv 3.4.2 с Python 3.6.3 в Windows 8.1

Ответы [ 3 ]

0 голосов
/ 30 января 2019

Я не смог установить FPS для своей камеры, поэтому мне удалось ограничить FPS в зависимости от времени, чтобы только 1 кадр в секунду превращался в остальную часть моего кода. Это не точно, но мне не нужно точно, просто ограничитель вместо 30 кадров в секунду. НТН

import time

fpsLimit = 1 # throttle limit
startTime = time.time()
cv = cv2.VideoCapture(0)
While True:
    frame = cv.read
    nowTime = time.time()
    if (int(nowTime - startTime)) > fpsLimit:
        # do other cv2 stuff....
        startTime = time.time() # reset time
0 голосов
/ 30 января 2019

Установка частоты кадров не всегда работает так, как вы ожидаете. Это зависит от двух вещей:

  1. На что способна ваша камера.
  2. Поддерживает ли используемый вами текущий бэкэнд захвата изменение частоты кадров.

Итак, пункт (1). Ваша камера будет иметь список форматов, которые она может передавать на устройство захвата (например, ваш компьютер). Это может быть 1920x1080 при 30 кадрах в секунду или 1920x1080 при 60 кадрах в секунду, и это также определяет формат пикселей. Подавляющее большинство потребительских камер не позволяют вам изменять их частоту кадров с большей степенью детализации. И большинство библиотек захвата откажутся перейти на формат захвата, который камера не рекламирует.

Даже камеры машинного зрения, которые дают вам намного больше контроля, обычно предлагают только выбор частоты кадров (например, 1, 2, 5, 10, 15, 25, 30 и т. Д.). Если вам нужна неподдерживаемая частота кадров на аппаратном уровне, обычно единственный способ сделать это - использовать аппаратный запуск.

А точка (2). Когда вы используете cv.VideoCapture, вы действительно вызываете библиотеку для конкретной платформы, такую ​​как DirectShow или V4L2. Мы называем это бэкэндом. Вы можете точно указать, какой бэкэнд используется, используя что-то вроде:

cv2.VideoCapture(0 + cv2.CAP_DSHOW)

Существует множество CAP_X, но только некоторые из них будут применяться к вашей платформе (например, CAP_V4L2 только для Linux). В Windows принуждение системы к использованию DirectShow - неплохая ставка. Однако, как указано выше, если ваша камера сообщает только о том, что она может выдавать 30 кадров в секунду и 60 кадров в секунду, запрос 10 кадров в секунду будет бессмысленным. Хуже того, многие настройки просто сообщают True в OpenCV, когда они на самом деле не реализованы. Вы видели, что в большинстве случаев чтение параметров даст вам ощутимые результаты, однако, если параметр не реализован (например, экспозиция является распространенной, а не), то вы можете получить глупость.

Вам лучше подождать некоторое время, а затем прочитать последнее изображение.

Будьте осторожны с этой стратегией. Не делай этого:

while capturing:
    res, image = cap.read()
    time.sleep(1)

вам нужно убедиться, что вы постоянно очищаете буфер кадров камеры, иначе вы начнете видеть отставание в ваших видео. Должно работать что-то вроде следующего:

frame_rate = 10
prev = 0

while capturing:

    time_elapsed = time.time() - prev
    res, image = cap.read()

    if time_elapsed > 1./frame_rate:
        prev = time.time()

        # Do something with your image here.
        process_image()

Для такого приложения, как ручной детектор, лучше всего иметь поток, захватывающий изображения, и детектор, работающий в другом потоке (который также управляет GUI). Ваш детектор извлекает последнее захваченное изображение, запускает и отображает результаты (вам может потребоваться заблокировать доступ к буферу изображений во время чтения / записи). Таким образом, вашим узким местом является детектор, а не производительность камеры.

0 голосов
/ 29 августа 2018

Свойство CV_CAP_PROP_FPS пока работает только для видео. Если вы используете следующую команду:

fps = cap.get(cv2.CAP_PROP_FPS)

Возвращается ноль. Если вы хотите уменьшить количество кадров в секунду, вы можете увеличить параметр waitkey (). Например:

k = cv2.waitKey(100)
...