如何使 cv2.videoCapture.read() 更快?

Yu-*_*sai 9 multithreading opencv ffmpeg python-3.x pyffmpeg

我的问题 :

我正在研究我的计算机视觉项目。我使用 opencv(4.1.2) 和 python 来实现它。

我需要一种更快的方法将读取帧传递到我的计算机上的图像处理(Ubuntu 18.04 8 核 i7 3.00GHz 内存 32GB)。读取cv2.VideoCapture.read()帧(帧大小:720x1280)大约需要120~140ms。这太慢了。我的处理模块每次运行大约需要 40 毫秒。我们希望 25~30 FPS。

这是到目前为止我的演示代码:

import cv2
from collections import deque
from time import sleep, time
import threading


class camCapture:
    def __init__(self, camID, buffer_size):
        self.Frame = deque(maxlen=buffer_size)
        self.status = False
        self.isstop = False
        self.capture = cv2.VideoCapture(camID)


    def start(self):
        print('camera started!')
        t1 = threading.Thread(target=self.queryframe, daemon=True, args=())
        t1.start()

    def stop(self):
        self.isstop = True
        print('camera stopped!')

    def getframe(self):
        print('current buffers : ', len(self.Frame))
        return self.Frame.popleft()

    def queryframe(self):
        while (not self.isstop):
            start = time()
            self.status, tmp = self.capture.read()
            print('read frame processed : ', (time() - start) *1000, 'ms')
            self.Frame.append(tmp)

        self.capture.release()

cam = camCapture(camID=0, buffer_size=50)
W, H = 1280, 720
cam.capture.set(cv2.CAP_PROP_FRAME_WIDTH, W)
cam.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, H)


# start the reading frame thread
cam.start()

# filling frames
sleep(5)

while True:
  frame = cam.getframe() # numpy array shape (720, 1280, 3)

  cv2.imshow('video',frame)
  sleep( 40 / 1000) # mimic the processing time

  if cv2.waitKey(1) == 27:
        cv2.destroyAllWindows()
        cam.stop()
        break

Run Code Online (Sandbox Code Playgroud)

我尝试过的:

  1. 多线程 - 一个线程仅读取帧,另一个线程执行图像处理操作。 这不是我想要的。因为我可以设置一个缓冲区双端队列,例如保存 50 帧。但帧读取线程的工作速度约为帧/130ms。我的图像处理线程的工作速度约为帧/40 毫秒。然后双端队列就用完了。所以我已经尝试过解决方案。但不是我需要的。

  2. 这个主题是我发现最接近我的问题的讨论。但不幸的是,我尝试了公认的解决方案(讨论下方的两个解决方案)。

其中一个解决方案(6 个竖起大拇指)指出,他可以在 Mac 上以 1 秒的间隔读取并保存 100 帧。为什么我的机器无法处理帧读取工作?我错过了什么吗?我的安装使用了 conda 和 pip conda install -c conda-forge opencvpip install opencv-python(是的,我都尝试了。)

另一个解决方案(1 个赞)使用 ffmpeg 解决方案。但它似乎适用于视频文件,但不适用于相机设备?

  1. 调整 c2.waitKey() :该参数仅控制视频显示时的频率。不是一个解决方案。

然后,我知道我只需要一些关键字即可。

上面的代码是到目前为止我的演示代码,我想要一些方法或指南来使 videoCapture.read() 更快。也许是在 videoCapture 对象或其他相机读取模块中使用多线程的方法。

有什么建议么?

Vu *_*ong 0

长的。

我使用以下设置进行了检查,如果增加帧大小 opencv 会降低总 fps。也许这是一个错误。

1920x1080:FPS:5.0,宽度:1920.0,高度:1080.0,延迟= 150ms

https://i.stack.imgur.com/1ZQ7v.jpg

1280x720:FPS:10.0,宽度:1280.0,高度:720.0,延迟 = 60ms

https://i.stack.imgur.com/tDV3R.jpg

640x480:FPS:30.0,宽度:640.0,高度:480.0,延迟 = 5ms

https://i.stack.imgur.com/cfMDc.jpg

但通过使用其他应用程序(例如Cheese),我们仍然可以在1920x1080分辨率下获得完整的30fps。请注意,设置 CAP_PROP_BUFFERSIZE 值也没有帮助。

那么就会出现一个问题:“我们如何克服这个问题?”。在这个阶段,你只有2个选择:

  1. 将帧分辨率降低为 640x480
  2. 使用其他框架

希望这有帮助。