OpenCV-Python:如何从实时视频流中获取最新帧或跳过旧帧

Posted

技术标签:

【中文标题】OpenCV-Python:如何从实时视频流中获取最新帧或跳过旧帧【英文标题】:OpenCV-Python: How to get latest frame from the live video stream or skip old ones 【发布时间】:2017-12-31 19:37:50 【问题描述】:

我已在 Python 中将 IP 摄像头与 OpenCV 集成,以便从实时流中逐帧完成视频处理。我已将相机 FPS 配置为 1 秒,这样我就可以在缓冲区中每秒获得 1 帧来处理,但我的算法需要 4 秒来处理每一帧,导致缓冲区中未处理的帧停滞不前,随着时间的推移不断增长 &造成指数级延迟。为了解决这个问题,我又创建了一个线程,我正在调用 cv2.grab() API 来清理缓冲区,它将指针移动到每次调用中的最新帧。在主线程中,我调用了retrieve() 方法,它为我提供了第一个线程抓取的最后一帧。通过这种设计,帧停滞问题得到了解决,指数延迟也被消除了,但仍然无法消除 12-13 秒的恒定延迟。我怀疑当 cv2.retrieve() 被调用时,它没有得到最新的帧,而是最新帧的第 4 帧或第 5 帧。 OpenCV 中是否有任何 API 或任何其他设计模式来解决此问题,以便我可以获取最新的帧来处理。

【问题讨论】:

当你的算法消耗的速度比信息产生的速度慢时,为什么你需要一个大的缓冲区。我的建议是使用只有两个图像插槽的缓冲区。从相机写入(写入缓冲区,仅一张图像)和其他读取以进行处理(读取缓冲区,仅一张图像)的一种。覆盖来自相机的新图像上的写入缓冲区。 @harshkn 你能告诉我如何减少缓冲区大小吗?我在 Ubuntu 16.04 的 Raspberry Pi 上尝试了“video.set(cv2.CAP_PROP_BUFFERSIZE, 1)”。结果显示一条消息“VIDEOIO ERROR: V4L2: setting property #38 is not supported True” 看看Python OpenCV streaming from camera - multithreading, timestamps、How to capture multiple camera streams with OpenCV和Video Streaming from IP Camera in Python Using OpenCV cv2.VideoCapture c++ - OpenCV VideoCapture lag due to the capture buffer - Stack Overflow 中有一些很好的答案和详细的解释(和解决方法); 然而答案在 C++ 中,您必须将其移植到 Python。 【参考方案1】:

如果您不介意牺牲速度。 你可以创建一个 python 生成器来打开相机并返回帧。

def ReadCamera(Camera):
    while True:
        cap = cv2.VideoCapture(Camera)
        (grabbed, frame) = cap.read()
        if grabbed == True:
            yield frame

现在当你想处理帧时。

for frame in ReadCamera(Camera):
      .....

这工作得很好。除了打开和关闭相机会加起来。

【讨论】:

以上是关于OpenCV-Python:如何从实时视频流中获取最新帧或跳过旧帧的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV-python视频入门

如何通过浏览器从网络摄像头获取实时流视频详细信息到 python?

如何从 PHPickerViewController 委托获取实时照片或视频

实现抖音视频抖动效果---OpenCV-Python开发指南(53)

初识OpenCV-Python - 005: 识别视频中的蓝色

如何使用 OpenCV-Python 从英特尔实感 D415 获取 IR1 和 IR2 摄像头图像?