如何提高 OpenCV cv2.VideoCapture(0).read() 的性能

2024-02-11

我在使用 intel core i7-4510u 的 Kali linux 上运行此脚本:

import cv2
from datetime import datetime
vid_cam = cv2.VideoCapture(0)
vid_cam.set(cv2.CAP_PROP_FPS, 25)
vid_cam.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
vid_cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)

lastDate = datetime.now().second
fcount = 0
while(vid_cam.isOpened()):
    if(datetime.now().second>lastDate):
        lastDate = datetime.now().second
        print("Fps: " + str(fcount))
        fcount = 0
    else:
        fcount += 1
    ret, image_frame = vid_cam.read()
    cv2.imshow('frame', image_frame)
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
vid_cam.release()
cv2.destroyAllWindows()

如果我运行它,它会打印Fps: 4.
如果我检查任务管理器我的cpu大约是2%.
问题可能出在哪里?


大多数时候,人们不会考虑数据速率(带宽)需要通过网络获取数据。

1920 x 1080 像素、30 FPS、每像素 24 位需要 1.5 Gbit/s。那不适合通过 USB 2。

这就是为什么许多网络摄像头实施压缩。常见的压缩是 MJPEG,即 JPEG 作为视频。

您可以告诉 OpenCV 告诉媒体 API(V4L、dshow、MSMF、AVFoundation...)从相机请求该信息。我了解到,它自己不会。

# cap = cv.VideoCapture(...)
cap.set(cv.CAP_PROP_FOURCC, cv.VideoWriter_fourcc(*"MJPG"))

每帧数据较少意味着传输速度更快,每次允许更多帧。

当将其与其他属性(FRAME_WIDTH 等)混合时,顺序很重要。我相信 FOURCC 设置需要放在第一位,但如果这没有帮助,请尝试其他命令。

当网络摄像头注意到 USB 控制器上没有足够的可用数据速率时,它可能会决定减小帧大小或帧速率,或应用更强的压缩(更糟糕的图片)。当您将多个相机连接到同一个 USB 集线器时,这will发生。这种协商可能会导致打开需要几秒钟,甚至一分钟。如果打开相机很慢,可能 USB 控制器已经为其他设备预留了一些带宽。


What does影响帧速率的是当该循环中的其他代码花费大量时间时!无法解决这个问题,除非使这部分代码更快。

什么会not一般来说,重要的是将阅读内容转移到自己的线程中。在 OpenCV 案例中(imshow),线程根本没有任何意义。线程只有在存在时才有意义还要别的吗除了处理下一帧(例如 GUI 循环)之外,还可以用通常等待的时间来完成。与消费者的沟通需要适当。繁忙的循环不是解决方案。

在实际 GUI 的情况下(notOpenCV 的imshow),正确的做法is一个线程,但它需要在框架进入时更新小部件。必须不任何重复读取变量并分配小部件图像或任何内容的旋转循环。

相机将按照自己的节奏生成帧(无论您做什么),并将它们放入队列中。读取一个框架的成本相当低(但并非没有)。

您必须从相机读取数据,否则帧会排队。如果您的阅读速度比相机的帧速率慢,您会看到延迟增加,即相机前面的移动需要几秒钟才能显示在屏幕上。

如果您尝试更快地读取,则 read() 调用将阻塞,直到有可用的帧为止。那么你就会在那个通话中“浪费”时间。那时你会做什么?你还没有新数据,所以没有什么可以计算的,直到该帧到达。还不如再等等,对吧?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何提高 OpenCV cv2.VideoCapture(0).read() 的性能 的相关文章

随机推荐