0


消除Python OpenCV显示摄像头画面的延迟

1. 问题描述

用 Python 通过 OpenCV显示摄像头画面时,如果对视频帧进行一些处理,常常会遇到一个问题,显示的画面比眼睛看到真实场景慢几秒甚至更多,给用户的体验不好。
在这里插入图片描述

画面延迟与卡顿的区别: 卡顿是指视频播放时,出现一顿一顿的现象,通常每秒播放速率少于10帧就可以感受到。摄像头画面出现卡顿,通常也会造成延迟。

2. 画面延迟原因

在视频处理应用程序中,由于对图像帧进行处理,通常会消耗一些时间,而OpenCV低层读帧缓存队列会保存未读的图像,用 read()方法读出是缓存里的帧,不是摄像头当前的帧。缓存中的帧较多时,就出现了延迟。

解决方法

自定义1个无缓存读视频的VideoCapture接口类,来代替OpenCV的VideoCapture类。
开发步骤:
1) 建立1个队列queue
2) 开启1个子线程, 实时读取摄像头视频帧,队列中总是保存最后一帧,删除旧帧。
3) 显示时,从新接口类的队列中读取帧。

实现代码

import cv2
import queue
import threading
import time

# 自定义无缓存读视频类classVideoCapture:"""Customized VideoCapture, always read latest frame"""def__init__(self, name):
        self.cap = cv2.VideoCapture(name)
        self.q = queue.Queue(maxsize=3)
        self.stop_threads =False# to gracefully close sub-thread
        th = threading.Thread(target=self._reader)
        th.daemon =True# 设置工作线程为后台运行
        th.start()# 实时读帧,只保存最后一帧def_reader(self):whilenot self.stop_threads:
            ret, frame = self.cap.read()ifnot ret:breakifnot self.q.empty():try:
                    self.q.get_nowait()except queue.Empty:pass
            self.q.put(frame)defread(self):return self.q.get()defterminate(self):
        self.stop_threads =True
        self.cap.release()# 测试自定义VideoCapture类
cap = VideoCapture(0)whileTrue:
    frame = cap.read()
    time.sleep(0.10)# 模拟耗时操作,单位:秒    
    cv2.imshow("frame", frame)ifchr(cv2.waitKey(1)&255)=='q':
        cap.terminate()break

即使对视频帧的处理时间过长,出现卡顿,由于新类会将未处理的帧丢弃,总是读取摄像头当前帧,因此消除了延迟,画面还是实时的。

实际应用时,可在本例代码基础上,进行优化。


本文转载自: https://blog.csdn.net/captain5339/article/details/128857313
版权归原作者 __弯弓__ 所有, 如有侵权,请联系我们删除。

“消除Python OpenCV显示摄像头画面的延迟”的评论:

还没有评论