无法使OpenCV 3.1 FPS超过~15 FPS

Unable to get OpenCV 3.1 FPS over ~15 FPS

本文关键字:FPS 超过 OpenCV      更新时间:2023-10-16

我下面有一些非常简单的性能测试代码,用于在2011年末的Macbook Pro上使用OpenCV 3.1 + Python3测量我的网络摄像头的FPS:

cap = cv2.VideoCapture(0)
count = 0
start_time = time.perf_counter()
end_time = time.perf_counter()
while (start_time + 1) > end_time:
    count += 1
    cap.read()
    # Attempt to force camera FPS to be higher
    cap.set(cv2.CAP_PROP_FPS, 30)
    end_time = time.perf_counter()
print("Got count", count)

不做处理,甚至不显示图像或在另一个线程中这样做,我只得到大约15 FPS。

尝试使用cap.get(cv2.CAP_PROP_FPS)访问相机的FPS,我得到0.0.

知道为什么吗?

我已经在网上搜索了很多答案,所以我想过的事情:

  • 我用发布标志构建OpenCV,所以它不应该做额外的调试逻辑

  • 尝试手动设置每帧FPS(见上文)

  • 我的FPS与其他应用程序(例如Chrome中的相机玩具)是30FPS

  • 在主线程上的应用程序中没有工作正在完成,因此将视频捕获逻辑放在另一个线程中,正如大多数其他帖子建议的那样,不应该产生差异

编辑**附加细节:似乎我捕捉的第一帧很快,然后随后的帧更慢;似乎这可能是一个缓冲区问题(即相机在第一帧后暂停,因为必须分配一个新的缓冲区来写?)

调整代码以计算每次读取后的平均FPS:

 cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_CONVERT_RGB, False)
cap.set(cv2.CAP_PROP_FPS, 30)
start_time = time.perf_counter()
count = 0
cv2.CAP_PROP_FPS
end_time = time.perf_counter()
while True:
    count += 1
    ret, frame = cap.read()
    end_time = time.perf_counter()
    print("Reached FPS of: ", count / (end_time - start_time))

我得到一帧大约30FPS,然后随后的帧更慢:

达到FPS: 27.805818385257446

达到FPS: 19.736237223924398

达到FPS: 18.173748156583795

达到FPS: 17.214809956810114

达到FPS: 16.94737657138959

达到FPS: 16.73624509452099

达到FPS: 16.33156408530572

编辑**截至10月20日,仍然没有运气。我最好的猜测是存在一些内存传输问题,因为相机本身可以根据其他应用程序的能力以30帧/秒的速度拍摄。

这不是回答。由于原问题中的评论太长,无法引起您的注意。我在外面发帖。

首先,CV_CAP_PROP_FPS返回0是正常的。OpenCV for Python只是OpenCV c++的包装器。据我所知,这个属性只适用于视频文件,而不是相机。你必须自己计算FPS(就像你的编辑)。

第二,OpenCV有一个bug,总是将图像从相机转换为RGB https://github.com/opencv/opencv/issues/4831。普通摄像机通常使用YUYV色。这要花很多时间。你可以检查所有支持的分辨率+ fps https://trac.ffmpeg.org/wiki/Capture/Webcam。我看到一些相机不支持RGB颜色和OpenCV强制获得RGB,并采取糟糕的FPS。由于相机的限制,在相同的编解码器中,分辨率越高,fps越慢。在不同支持的编解码器中,相同分辨率下的输出越大,fps越慢。例如,我的相机支持yuyv和mjpeg,在高清分辨率下,yuyv的最大帧数是10帧,而mjpeg的最大帧数是30帧。

所以,首先你可以尝试ffmpeg executable来获取帧。在确定错误来自何处后,如果ffmpeg工作良好,您可以使用ffmpeg库(不是ffmpeg可执行文件)从相机获取帧(OpenCV使用ffmpeg用于大多数视频I/O,包括相机)。

请注意,我只在c++语言中使用ffmpeg和OpenCV,而不是Python。使用ffmpeg库是另一个很长的故事。

祝你好运!