天天看點

解決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