Низкий FPS при использовании OpenCv с PiCamera (python) - PullRequest
1 голос
/ 06 мая 2020

Я пытаюсь связать свою программу OpenCV с моей Raspberry Pi PiCamera. Каждый раз, когда я использую OpenCV для захвата видео, он резко снижает FPS. Когда я снимаю видео с помощью библиотеки PiCamera, все в порядке и плавно.

  1. Почему это происходит?
  2. Есть ли способ исправить это?

Это мой код:

import time
import RPi.GPIO as GPIO
from PCA9685 import PCA9685
import numpy as np
import cv2

try:


    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FPS, 90)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 700)

    while(True):
        ret, frame = cap.read()

        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

# When everything is done, release the capture


except:
    pwm.exit_PCA9685()
    print ("\nProgram end")
    exit()
cap.release()
cv2.destroyAllWindows()

Это ошибка, которую я получаю:

enter image description here

1 Ответ

1 голос
/ 07 мая 2020
  1. Прежде всего, это предупреждения, а не ошибки.

  2. Уменьшите размер видео. Укажите размер.

  3. cv2.VideoCapture имеет некоторые проблемы, поскольку он буферизует кадры, и кадры ставятся в очередь, поэтому, если вы выполняете некоторую обработку, а скорость меньше пропускной способности VideoCapture видео будет замедляться.

Итак, вот безбуферный VideoCapture.

video_capture_Q_buf.py

import cv2, queue as Queue, threading, time


is_frame = True
# bufferless VideoCapture


class VideoCaptureQ:

    def __init__(self, name):
        self.cap = cv2.VideoCapture(name)
        self.q = Queue.Queue()
        t = threading.Thread(target=self._reader)
        t.daemon = True
        t.start()

    # read frames as soon as they are available, keeping only most recent one
    def _reader(self):
        while True:
            ret, frame = self.cap.read()
            if not ret:
                global is_frame
                is_frame = False
                break
            if not self.q.empty():
                try:
                    self.q.get_nowait()   # discard previous (unprocessed) frame
                except Queue.Empty:
                    pass
            self.q.put(frame)

    def read(self):
        return self.q.get()

Использование:

test.py

import video_capture_Q_buf as vid_cap_q # import as alias
from video_capture_Q_buf import VideoCaptureQ # class import
import time

cap = VideoCaptureQ(vid_path)

while True:

    t1 = time.time()

    if vid_cap_q.is_frame == False:
        print('no more frames left')
        break

    try:
        ori_frame = cap.read()
        # do your stuff
    except Exception as e:
        print(e)
        break
    t2 = time.time()
    print(f'FPS: {1/(t2-t1)}')

...