背景:
基于YOLO系列的目标检测器能够实时监测目标,为了能够在视频监控系统中加入目标检测功能,采用YOLOv5s监测模型,结合RTSP服务器,采用客户端/服务器(C/S)模式利用ffmpeg进行实时监测视频推拉流。
整体项目结构:
1.demo
- FlowPuser.py:定义了一个推流器,主要是采用ffmpeg进行参数化;
- Yolov5Compent.py:定义了YOLOv5的一些处理函数,比如检测、画框等,因此如果需要采用YOLO的其它系列需要修改此代码;
- main.py:主程序,采用RTSP作为服务器,输入rtsp地址、创建YOLOv5检测器对象,进行实时的推拉流。
2.models
- yolov5s.onnx:采用官方代码库中的yolov5s.pt转换得到的,采用onnx文件进行部署;
3.其它
- coco.names:coco数据集的类别,用于目标检测;
- READM.md;
- requirements.txt:项目运行所需的依赖库,这是YOLOv8官方的需求文档,可以参考这个安装依赖库。
实现过程:
1.采用conda创建一个虚拟环境,在虚拟环境中运行项目(如果缺少库,可以根据提示下载对应库);
pip install -r requirements.txt
2.首先现在rtsp-server服务器(如果采用的是虚拟机或者是服务器,可以下载对应的linux服务器),我下载的是图片上的两个版本。下载完毕后直接打开文件夹下的mediamtx.exe;
Releases · bluenviron/mediamtx (github.com)
3.运行服务器后,在main函数中修改rtsp的地址;
import argparse
import time
import cv2
import imutils
from FlowPuser import StreamPusher
from Yolov5Compents import YOLOv5
rtmp_server = 'rtmp://你的IP地址:1935/video'
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--imgpath', type=str, default='0', help="image path or camera index")
parser.add_argument('--modelpath', type=str, default='../models/yolov5s.onnx', help="onnx filepath")
parser.add_argument('--confThreshold', default=0.3, type=float, help='class confidence')
parser.add_argument('--nmsThreshold', default=0.5, type=float, help='nms iou thresh')
args = parser.parse_args()
yolov5_detector = YOLOv5(args.modelpath, conf_thres=args.confThreshold, iou_thres=args.nmsThreshold)
imgpath = args.imgpath
cap = None
pusher = None
try:
# 处理摄像头 or 视频文件
if imgpath.isnumeric() and len(imgpath) == 1:
cap = cv2.VideoCapture(int(imgpath)) # 读取摄像头
else:
cap = cv2.VideoCapture(imgpath) # 读取视频文件
if not cap.isOpened():
print(f"Error: Could not open {imgpath}")
exit()
pusher = StreamPusher(rtmp_server)
# 获取摄像头 FPS
fps = cap.get(cv2.CAP_PROP_FPS)
print(f"摄像头 FPS: {fps}")
fail_count = 0
MAX_FAILS = 30 # 最多允许 30 帧读取失败
prev_time = time.time()
while True:
success, srcimg = cap.read()
if not success:
fail_count += 1
if fail_count > MAX_FAILS:
print("连续30帧无法读取,退出")
break
continue # 跳过当前帧
srcimg = imutils.resize(srcimg, width=640)
# 目标检测
boxes, scores, class_ids = yolov5_detector.detect(srcimg)
# 计算 FPS
cur_time = time.time()
fps = 1 / (cur_time - prev_time)
prev_time = cur_time
print(f"当前 FPS: {fps:.2f}")
# 画出检测结果
dstimg = yolov5_detector.draw_detections(srcimg, boxes, scores, class_ids)
# 推送到 RTMP 服务器
try:
pusher.streamPush(dstimg)
except Exception as e:
print(f"推流失败: {e}")
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print(f"程序异常: {e}")
finally:
if cap:
cap.release()
if pusher:
pusher.close()
cv2.destroyAllWindows()
4.打开vlc的网络串流进行拉流(输入步骤2中的rtmp_server地址):
效果展示
效果展示https://github.com/23jisuper/yolov5-ffmpeg
代码地址:
代码地址 (效果还行的话点个星星⭐。😊)