天天看点

解决Opencv读取实时视频流无法刷新当前帧的问题

目前有这样的需求:使用Opencv读取实时视频流数据,做算法处理,因为算法本身处理速度有限,因此会产生每次读取到的帧不是当前帧的问题,体验很差。

例如:

import cv2
cap=cv2.VideoCaptrue("rtsp://....")
while true
	ret,frame=cap.read()
	if ret=True:
		process(frame)#此处为图像处理的代码
		cv2.imshow("test",frame)
		if chr(cv2.waitKey(1)&255) == 'q':
			break
           

由以上代码可见,由于process()会产生耗时,所以每次cap.read()读取到的都不是实时的当前帧,可能是缓存中的帧。

解决方法(非原创):

import cv2
import queue
import threading

# 无缓存读取视频流类
class VideoCapture:

  def __init__(self, name):
    self.cap = cv2.VideoCapture(name)
    self.q = queue.Queue()
    t = threading.Thread(target=self._reader)
    t.daemon = True
    t.start()

  # 帧可用时立即读取帧,只保留最新的帧
  def _reader(self):
    while True:
      ret, frame = self.cap.read()
      if not ret:
        break
      if not self.q.empty():
        try:
          self.q.get_nowait()   # 删除上一个(未处理的)帧
        except queue.Empty:
          pass
      self.q.put(frame)

  def read(self):
    return self.q.get()

cap = VideoCapture("rtsp://....")
while True:
  frame = cap.read()
  cv2.imshow("frame", frame)
  if chr(cv2.waitKey(1)&255) == 'q':
    break