1. 問題の説明
Python を使用して OpenCV を介してカメラ画像を表示する場合、ビデオ フレームに何らかの処理が実行されると、表示される画像が目で見る実際のシーンよりも数秒以上遅くなるという問題が発生することがよくあります。ユーザーは良くない。
画像の遅延とスタッタリングの違い:スタッタリングとは、ビデオの再生時、通常は再生レートが 1 秒あたり 10 フレーム未満の場合に起こるスタッタリング現象を指します。通常、カメラの途切れも遅延の原因となります。
2. 画面遅延の原因
ビデオ処理アプリケーションでは、通常、画像フレームの処理に時間がかかり、OpenCV の低レベル読み取りフレーム バッファー キューが未読の画像を保存し、read() メソッドがカメラの現在のフレームではなくキャッシュ内のフレームを読み取ります。 .フレームです。キャッシュ内に多くのフレームが存在すると、遅延が発生します。
解決
OpenCV の VideoCapture クラスを置き換えるために、バッファなしのビデオ読み取り用に VideoCapture インターフェイス クラスをカスタマイズします。
開発手順:
1) キューキューを作成します。
2) サブスレッドを開始してカメラビデオフレームをリアルタイムで読み取り、常に最後のフレームをキューに保存し、古いフレームを削除します。
3) 表示上で、新しいインターフェイス クラスのキューからフレームを読み取ります。
実装コード
import cv2
import queue
import threading
import time
# 自定义无缓存读视频类
class VideoCapture:
"""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):
while not self.stop_threads:
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()
def terminate(self):
self.stop_threads = True
self.cap.release()
# 测试自定义VideoCapture类
cap = VideoCapture(0)
while True:
frame = cap.read()
time.sleep(0.10) # 模拟耗时操作,单位:秒
cv2.imshow("frame", frame)
if chr(cv2.waitKey(1)&255) == 'q':
cap.terminate()
break
ビデオ フレームの処理時間が長すぎてフリーズした場合でも、新しいクラスは未処理のフレームを破棄し、常にカメラの現在のフレームを読み取るため、遅延がなくなり、画像は依然として本物です。時間。
実際のアプリケーションでは、このサンプルコードを基に最適化することができます。