一、测试摄像头的视频流
在进行动态检测视频流的对象之前,需要先把摄像头的视频播放出来。
找一个摄像头,配置好IP地址,找到它的流播放地址,比如我手上用的地址是:
rtsp://192.168.12.100/stream1
把这个地址复制到播放器里打开,可以进行播放,表示这个流是我们可以获取的,有流需要用户名和密码,具体看自己使用的
我使用的PotPlayer播放器
OK,已经正常播放视频
二、在python里播放视频流
我们采用opencv。
OpenCV(open source computer vision library)是一个基于BSD许可(开源)发行的跨平台计算机视觉库,是一款应用很广的开源库。
首先先安装opencv
pip install opencv-python
安装成功:
新建一个play.py文件
编写如下代码
import cv2
rtsp_url = "rtsp://192.168.12.100/stream1"
cap = cv2.VideoCapture(rtsp_url)
# 创建可调整大小的窗口
cv2.namedWindow('RTSP Stream', cv2.WINDOW_NORMAL)
while True:
ret, frame = cap.read()
if not ret:
print("连接中断,尝试重连...")
cap = cv2.reopen_stream(rtsp_url) # 自定义重连函数
continue
# 显示视频帧
cv2.imshow('RTSP Stream', frame)
# 监听窗口调整事件
key = cv2.waitKey(1) & 0xFF
if key == 27: # ESC键退出
break
cap.release()
cv2.destroyAllWindows()
然后执行,等待一会,播放成功
三、实现视频流动态检测显示检测目标
新建一个detect_rtsp.py
import cv2
from ultralytics import YOLO
import time
class RTSPYOLODetector:
def __init__(self, rtsp_url, model_path="yolo11n.pt"):
self.rtsp_url = rtsp_url
self.model = YOLO(model_path) #
self.cap = None
self.last_frame = None
self.reconnect_interval = 3 # 重连等待时间(秒)
self.frame_skip = 2 # 跳帧检测以降低延迟
def start_detection(self):
cv2.namedWindow("YOLO RTSP Detection", cv2.WINDOW_NORMAL)
self._connect_stream()
frame_count = 0
while True:
try:
if not self.cap.isOpened():
self._reconnect()
continue
ret, frame = self.cap.read()
if not ret:
print("视频流中断,尝试重连...")
self._reconnect()
continue
# 跳帧处理:每3帧处理1次以降低延迟
frame_count += 1
if frame_count % self.frame_skip != 0:
continue
# YOLO检测
results = self.model.predict(
frame,
conf=0.6, # 置信度阈值
iou=0.45, # IOU阈值
classes=[0, 2, 3, 5], # 只检测人、车、摩托车、公交车
verbose=False
)
# 绘制检测结果
annotated_frame = results[0].plot()
# 自适应窗口缩放
h, w = annotated_frame.shape[:2]
win_w = cv2.getWindowImageRect("YOLO RTSP Detection")[2]
win_h = int(win_w * h / w)
resized_frame = cv2.resize(annotated_frame, (win_w, win_h))
cv2.imshow("YOLO RTSP Detection", resized_frame)
# ESC退出
if cv2.waitKey(1) == 27:
break
except Exception as e:
print(f"发生错误: {str(e)}")
self._reconnect()
self.cap.release()
cv2.destroyAllWindows()
def _connect_stream(self):
if self.cap:
self.cap.release()
# 优化RTSP参数减少延迟
self.cap = cv2.VideoCapture(self.rtsp_url)
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 缓冲区大小
self.cap.set(cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 3000) # 超时时间
time.sleep(self.reconnect_interval)
if __name__ == "__main__":
# RTSP示例地址(替换为实际摄像头地址)
rtsp_url = "rtsp://192.168.12.100/stream1"
# 初始化检测器
detector = RTSPYOLODetector(
rtsp_url,
model_path="yolo11n.pt"
)
detector.start_detection()
运行,效果如下
四、给检测框添加尺寸显示
新建一个detect_rtsp_xy.py
import cv2
from ultralytics import YOLO
import time
class RTSPYOLODetector:
def __init__(self, rtsp_url, model_path="yolo11n.pt"):
self.rtsp_url = rtsp_url
self.model = YOLO(model_path)
self.cap = None
self.last_frame = None
self.reconnect_interval = 3 # 重连等待时间(秒)
self.frame_skip = 2 # 跳帧检测以降低延迟
def start_detection(self):
cv2.namedWindow("YOLO RTSP Detection", cv2.WINDOW_NORMAL)
self._connect_stream()
frame_count = 0
while True:
try:
if not self.cap.isOpened():
self._reconnect()
continue
ret, frame = self.cap.read()
if not ret:
print("视频流中断,尝试重连...")
self._reconnect()
continue
# 跳帧处理:每3帧处理1次以降低延迟
frame_count += 1
if frame_count % self.frame_skip != 0:
continue
# YOLO检测
results = self.model.predict(
frame,
conf=0.6,
iou=0.45,
classes=[0, 2, 3, 5],
verbose=False
)
# 创建带尺寸标注的画面
annotated_frame = frame.copy()
if results[0].boxes:
for box in results[0].boxes:
# 获取坐标、类别、置信度
x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())
cls_id = int(box.cls[0])
conf = float(box.conf[0])
width = x2 - x1
height = y2 - y1
# 绘制检测框
color = (0, 255, 0) # 绿色边框
cv2.rectangle(annotated_frame, (x1, y1), (x2, y2), color, 2)
# 构造带尺寸的标签
class_name = results[0].names[cls_id]
label = f"{class_name} {conf:.2f} W:{width} H:{height}"
# 计算文本位置(确保在画面内)
(text_w, text_h), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 2)
text_y = y1 - text_h - 5 if y1 > text_h + 5 else y1 + 20
# 绘制文本背景
cv2.rectangle(annotated_frame,
(x1, text_y - text_h - 5),
(x1 + text_w, text_y + 5),
color, -1)
# 绘制文本
cv2.putText(annotated_frame, label,
(x1, text_y),
cv2.FONT_HERSHEY_SIMPLEX,
0.6, (0, 0, 0), 2)
# 自适应窗口缩放
h, w = annotated_frame.shape[:2]
win_w = cv2.getWindowImageRect("YOLO RTSP Detection")[2]
win_h = int(win_w * h / w)
resized_frame = cv2.resize(annotated_frame, (win_w, win_h))
cv2.imshow("YOLO RTSP Detection", resized_frame)
# ESC退出
if cv2.waitKey(1) == 27:
break
except Exception as e:
print(f"发生错误: {str(e)}")
self._reconnect()
self.cap.release()
cv2.destroyAllWindows()
def _connect_stream(self):
if self.cap:
self.cap.release()
self.cap = cv2.VideoCapture(self.rtsp_url)
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
self.cap.set(cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 3000)
time.sleep(self.reconnect_interval)
if __name__ == "__main__":
rtsp_url = "rtsp://192.168.12.100/stream1"
detector = RTSPYOLODetector(rtsp_url, model_path="yolo11n.pt")
detector.start_detection()
运行效果如下: