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

标签 python performance opencv video video-streaming

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

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 as video。

您可以告诉 OpenCV 告诉媒体 API(V4L、dshow、MSMF、AVFoundation...)向相机请求。它不会自行消失,我了解到。

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

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

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

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


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

通常重要的是将阅读内容移到自己的线程中。在 OpenCV 的情况下(使用 imshow),线程根本没有意义。只有在通常等待的时间里除了处理下一帧(例如 GUI 循环)之外还有其他要完成的情况下,线程才有意义。与消费者的沟通需要适当。繁忙的循环不是解决方案。

在实际 GUI 的情况下(不是 OpenCV 的imshow),正确的做法一个线程,但它需要更新小部件作为一个框架进入。不得任何重复读取变量并分配小部件的图像或任何东西的旋转循环。

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

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

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

关于python - 如何提高 OpenCV cv2.VideoCapture(0).read() 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54933801/

相关文章:

java - 有没有办法找到匹配谓词的第一个元素?

sql-server - 同义词对 SQL Server 中链接服务器的性能影响

python - cv2.imshow() 函数如何在 BGR 模型中工作?

python - 如何将numpy数组更改为灰度opencv图像

python - 有没有办法测试 SQLAlchemy 连接?

python - Python 中的错误消息 "MemoryError"

c++ - 人脸识别分类器

python - 如何获取 pandas xlsxwriter 对象的二进制内容以进行 Dropbox 上传

android - picasso 什么时候刷新图像缓存

c++ - OpenCV C++ Mat == 运算符