【问题标题】:Low FPS using OpenCv with PiCamera (python)使用 OpenCv 和 PiCamera(python)的低 FPS
【发布时间】:2020-05-06 08:03:31
【问题描述】:

我正在尝试将我的 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()

这是我遇到的错误:

【问题讨论】:

  • 您似乎没有设置视频的尺寸。
  • 这解决了我的 FPS 问题...但我仍然在终端中收到错误消息。任何想法这意味着什么或可能导致它的原因是什么?还意识到实际运动与视频上投影的内容之间存在 0.5 秒的延迟
  • 尝试将循环更改为仅 while True: 而不使用 cap.isOpened()。另外请更新您的代码以显示您实际运行的内容。
  • @MarkSetchell 我更新了我的代码。正如你所说,我也改变了循环。您的回答在一定程度上解决了我的 FPS 问题(通过给它尺寸)。我意识到设置 FPS >= 100 会引发异常。现在我主要关心的是初始错误消息的含义以及为什么会产生它?随意发布您的尺寸评论作为答案(这是一个可行的解决方案)。

标签: python python-3.x opencv cv2


【解决方案1】:
  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)}')

【讨论】:

  • 如果我想要网络摄像头而不是保存的视频,我可以将 0 作为参数传入吗?
  • 是的,你可以。机制是一样的。
  • cv2.imshow('frame',ori_frame) 没有显示任何内容。它说我的 FPS 在 3 和 4 之间
  • 您能否检查一下您的网络摄像头是否配置正确?视频也会失败吗?
  • 我的网络摄像头配置正确。当我用视频测试它时,它给出了以下错误:open OpenCV | GStreamer 警告:打开 bin 时出错:意外引用“vid” - 忽略 ---------- isPipelinePlaying OpenCV | GStreamer 警告:GStreamer:管道尚未创建
猜你喜欢
  • 2015-09-02
  • 1970-01-01
  • 2018-04-11
  • 2019-06-25
  • 2015-06-28
  • 2015-05-17
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多