使用opencv和python抓帧时如何保持恒定的FPS?

时间:2019-06-25 18:09:00

标签: python python-3.x opencv video-capture webcam-capture

我正在使用OpenCV4和python 3来打开网络摄像头,抓取帧并将其显示在窗口中,就像提供的第一个代码教程here一样。但是,捕获不同的帧需要花费不同的时间:有时要花0.01 s的时间才能抓取,有时要花0.33 s的时间,在窗口中显示帧时会产生滞后。

在抓帧时是否有一种强制固定时间的方式,以便我可以看到视频而不会出现延迟?我认为OpenCV会发生这种情况,因为当我使用默认的Windows摄像头查看器进行查看时视频正常显示。

我已经尝试过的操作是使用time.sleep()等待一段时间,然后再次抓取框架。但这无济于事。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

3 个答案:

答案 0 :(得分:2)

一种可能的方法是在循环中设置时间戳,并跟踪显示最后一帧的时间。例如,只有经过一定时间后,您才显示框架。同时,您不断读取帧以使缓冲区保持空白以确保您拥有最新的帧。您不想使用foreach (string table in tablenames) { System.Console.WriteLine("*****" + table + "*****"); DataTable schemaTable = (cnn as OleDbConnection).GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, new Object[] { null, null, table}); int columnOrdinalForName = schemaTable.Columns["COLUMN_NAME"].Ordinal; foreach (DataRow r in schemaTable.Rows) { string keyName = r.ItemArray[columnOrdinalForName].ToString(); System.Console.WriteLine("\t" + keyName); foreach (DataColumn myProperty in mySchema.Columns) { Console.WriteLine(myProperty.ColumnName + " = " + r[myProperty].ToString()); } Console.WriteLine(); } ,因为它会冻结程序并且不会使缓冲区保持空状态。时间戳击中后,您将显示框架并重置时间戳。

time.sleep()

答案 1 :(得分:0)

我最近偶然发现了这个问题。我没有使用OpenCV的帧捕获,而是建立了一个单独的过程-使用ffmpeg捕获并将它们写入ramdisk。

Python的看门狗使我能够收到更新通知并启动OCR进程。

事实证明,它在控制捕获方面具有很多粒度,因此更快,更高效。

答案 2 :(得分:0)

正常运行时,此应用将在read()调用时暂停,直到流式网络摄像头的下一帧可用为止。流畅的显示取决于能否在不到1 / FPS秒的时间内执行添加到循环中的任何内容。它还取决于相机是否符合UVC要求,也可能取决于编码算法是否为MJPEG,大多数网络摄像头就是这种情况。但是,您看到延迟高达1/3秒这一事实令人感到好奇,因为这是mpeg或其他帧间编码器的典型GOP周期。

如果以上情况均不适用于您的情况,那么我怀疑该问题与平台相关,而不是OCV问题。您是否尝试过在另一个系统上重复该问题?