简体   繁体   中英

Low FPS using OpenCv with PiCamera (python)

I am trying to interface my OpenCV program with my Raspberry Pi PiCamera. Every time I use OpenCV to capture video, it drastically drops the FPS. When I capture video using PiCamera's Library, everything is fine and smooth.

  1. Why is this happening?
  2. Is there a way to fix it?

This is my code:

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

This is the error I'm getting:

在此处输入图像描述

  1. First of all, those are warnings not errors.

  2. Reduce the video dimension. Specify the dimension.

  3. cv2.VideoCapture has some problems as it buffers the frames, and the frames are queued so if you're doing some processing and the speed is less than the bandwidth of VideoCapture the video will be slowed down.

So, here is a bufferless 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()

Using it:

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)}')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM