- grab()函数【没奏效】
# 跳过无需处理的帧
grabbed = capture.grab()
if not grabbed:
print("跳过帧失败")
await send_message(websocket, "跳过帧失败 或 视频流已结束")
url = await websocket.recv()
break
# 获取最新的帧
retrieved, frame = capture.retrieve()
if not retrieved:
print("检测画面失败")
await send_message(websocket, "检测画面失败 或 视频流已结束")
url = await websocket.recv()
break
- 多线程【没奏效】
import cv2
import threading
import sys
class RTSCapture(cv2.VideoCapture):
_cur_frame = None
_reading = False
schemes = ["rtsp://","rtmp://"]
@staticmethod
def create(url, *schemes):
rtscap = RTSCapture(url)
rtscap.frame_receiver = threading.Thread(target=rtscap.recv_frame, daemon=True)
rtscap.schemes.extend(schemes)
if isinstance(url, str) and url.startswith(tuple(rtscap.schemes)):
rtscap._reading = True
elif isinstance(url, int):
pass
return rtscap
def isStarted(self):
ok = self.isOpened()
if ok and self._reading:
ok = self.frame_receiver.is_alive()
return ok
def recv_frame(self):
while self._reading and self.isOpened():
ok, frame = self.read()
if not ok: break
self._cur_frame = frame
self._reading = False
def read2(self):
frame = self._cur_frame
self._cur_frame = None
return frame is not None, frame
def start_read(self):
self.frame_receiver.start()
self.read_latest_frame = self.read2 if self._reading else self.read
def stop_read(self):
self._reading = False
if self.frame_receiver.is_alive(): self.frame_receiver.join()
if __name__ == '__main__':
if len(sys.argv) < 2:
print("usage:")
print("need rtsp://xxx")
sys.exit()
rtscap = RTSCapture.create(sys.argv[1])
rtscap.start_read()
while rtscap.isStarted():
ok, frame = rtscap.read_latest_frame()
if cv2.waitKey(100) & 0xFF == ord('q'):
break
if not ok:
continue
# inhere
cv2.imshow("cam", frame)
rtscap.stop_read()
rtscap.release()
cv2.destroyAllWindows()
- 重新定义VideoCapture类。【奏效】
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()
def release(self):
self.cap.release()
self.q = queue.Queue()
def get_resolution(self):
return self.cap.get(cv2.CAP_PROP_FRAME_WIDTH),self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
url = "xxx"
while True:
frame = capture.read()
if frame is None or len(frame) == 0:
print("画面检测失败 或 视频流已结束")
break
width, height = capture.get_resolution()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = Image.fromarray(np.uint8(frame))
# …… 算法