YOLOv8+ Deepsort+Pyqt5车速检测系统,支持多目标跟踪和车辆测速。
支持GPU加速,精度,速度快,适合用于交通管理和智能监控。模块化导入,也可导入其他权重文件进行识别跟踪。支持自定义配置,如显示标签、保存结果等
基于YOLOv8 + DeepSORT + PyQt5构建的多目标车辆测速系统的完整代码,支持:
✅ GPU 加速(CUDA)
✅ 多目标检测与跟踪(DeepSORT)
✅ 实时车速计算(基于帧间位移)
✅ 自定义配置(模型、置信度、IOU、设备等)
✅ 模块化设计,可导入任意 YOLO 权重文件
✅ 支持视频/摄像头输入
✅ 可视化界面(PyQt5),实时显示速度、轨迹、标签
以下文字及代码仅供参考学习
📁 项目结构
car_speed_detection_system/ ├── deep_sort_pytorch/ # DeepSORT 源码 ├── weights/ # 存放模型权重(如 yolov8n.pt) │ └── yolov8n.pt ├── outputs/ # 保存结果视频/图像 ├── testVideo/ # 测试视频 ├── detect.py # 核心推理逻辑(含测速) ├── GUI.py # PyQt5 图形界面 ├── requirements.txt └── README.md📦requirements.txt
ultralytics==8.2.0 opencv-python==4.8.0 PyQt5==5.15.9 numpy==1.24.3 scikit-image==0.21.0 matplotlib==3.6.3安装:
pipinstall-r requirements.txt💡 注:需从 GitHub 下载 DeepSORT 源码并放入
deep_sort_pytorch/文件夹中
👉 https://github.com/ifzhang/deep-sort-pytorch
🔧 1.detect.py—— YOLOv8 + DeepSORT + 车速计算核心模块
# detect.pyimportcv2importnumpyasnpfromultralyticsimportYOLOfromdeep_sort_pytorch.deep_sortimportDeepSortimporttorchimporttimeclassCarSpeedTracker:def__init__(self,model_path="weights/yolov8n.pt",device="cuda"iftorch.cuda.is_available()else"cpu"):self.model=YOLO(model_path)self.deepsort=DeepSort(max_dist=0.2,min_hits=3,nn_budget=100,max_iou_distance=0.7)self.device=device self.tracked_tracks={}# 存储每个 track_id 的历史位置self.fps=30# 默认 FPS,可根据实际调整self.camera_height=3.0# 相机高度(米),用于透视校正(可选)self.line_y=None# 计速线 y 坐标(可选)defset_fps(self,fps):"""设置视频帧率"""self.fps=fpsdefset_speed_line(self,y):"""设置计速线位置(如车道中间)"""self.line_y=ydefdetect_and_track(self,frame,conf=0.4,iou=0.5):# YOLO 检测results=self.model(frame,conf=conf,iou=iou,classes=[0,1,2,3,5,7])# car, truck, bus, motorcycle, bicycle, trainboxes=results[0].boxes.xyxy.cpu().numpy()scores=results[0].boxes.conf.cpu().numpy()cls_ids=results[0].boxes.cls.cpu().numpy()detections=[]foriinrange(len(boxes)):x1,y1,x2,y2=boxes[i]score=scores[i]cls_id=int(cls_ids[i])class_name=self.model.names[cls_id]detections.append([x1,y1,x2,y2,score,cls_id])# DeepSORT 跟踪tracked_boxes=self.deepsort.update(detections,frame)# 绘制结果annotated_frame=frame.copy()current_tracks={}speed_info={}forboxintracked_boxes:x1,y1,x2,y2,track_id,cls_id=box class_name=self.model.names[int(cls_id)]label=f"{track_id}:{class_name}"# 更新轨迹iftrack_idnotincurrent_tracks:current_tracks[track_id]={'bbox':(x1,y1,x2,y2),'cls':class_name}self.tracked_tracks[track_id]=[]# 计算速度iftrack_idinself.tracked_tracksandlen(self.tracked_tracks[track_id])>1:prev_x,prev_y=self.tracked_tracks[track_id][-1]curr_x,curr_y=(x1+x2)/2,(y1+y2)/2distance_px=np.sqrt((curr_x-prev_x)**2+(curr_y-prev_y)**2)speed_px_per_sec=distance_px*self.fps speed_kmh=speed_px_per_sec*0.001# 简化估算(需根据 GSD 校准)speed_info[track_id]=f"Speed:{speed_kmh:.1f}km/h"# 保存当前坐标self.tracked_tracks[track_id].append((curr_x,curr_y))# 绘制框和标签color=(0,255,0)ifclass_name=='car'else(255,0,0)cv2.rectangle(annotated_frame,(int(x1),int(y1)),(int(x2),int(y2)),color,2)cv2.putText(annotated_frame,label,(int(x1),int(y1)-10),cv2.FONT_HERSHEY_SIMPLEX,0.6,color,2)# 显示速度iftrack_idinspeed_info:cv2.putText(annotated_frame,speed_info[track_id],(int(x1),int(y1)+20),cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,0,255),2)returnannotated_frame,current_tracks,speed_info🖥️ 2.GUI.py—— PyQt5 可视化界面(带参数配置)
# GUI.pyimportsysimportcv2fromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QLabel,QPushButton,QVBoxLayout,QWidget,QHBoxLayout,QTextEdit,QComboBox,QSlider,QLineEdit,QFileDialog,QCheckBox,QSpinBox)fromPyQt5.QtGuiimportQImage,QPixmapfromPyQt5.QtCoreimportQt,QTimerimportnumpyasnpfromdetectimportCarSpeedTrackerclassCarSpeedDetectionApp(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("🚗 车速检测系统")self.resize(1200,800)self.tracker=CarSpeedTracker()self.cap=Noneself.timer=QTimer()self.timer.timeout.connect(self.update_frame)self.is_running=Falseself.current_video=Noneself.count_line_y=Noneself.init_ui()definit_ui(self):central_widget=QWidget()self.setCentralWidget(central_widget)layout=QHBoxLayout(central_widget)# 左侧控制面板control_panel=QWidget()control_layout=QVBoxLayout(control_panel)# 视频选择self.video_label=QLabel("视频:")self.video_input=QLineEdit()self.btn_select_video=QPushButton("选择视频")self.btn_select_video.clicked.connect(self.select_video)# 模型选择self.model_label=QLabel("模型:")self.model_combo=QComboBox()self.model_combo.addItems(["yolov8n.pt","yolov8s.pt","yolov8m.pt"])self.model_combo.currentIndexChanged.connect(self.change_model)# 参数滑动条self.conf_slider=QSlider(Qt.Horizontal)self.conf_slider.setMinimum(0)self.conf_slider.setMaximum(100)self.conf_slider.setValue(40)self.conf_label=QLabel("Conf: 0.4")self.iou_slider=QSlider(Qt.Horizontal)self.iou_slider.setMinimum(0)self.iou_slider.setMaximum(100)self.iou_slider.setValue(50)self.iou_label=QLabel("IOU: 0.5")# 设备选择self.device_combo=QComboBox()self.device_combo.addItems(["GPU","CPU"])self.device_combo.currentIndexChanged.connect(self.change_device)# 其他选项self.show_labels=QCheckBox("显示标签")self.show_speed=QCheckBox("显示速度")self.save_results=QCheckBox("保存结果")self.save_frames=QCheckBox("保存视频帧")self.show_mask=QCheckBox("显示掩码图")# FPS 设置self.fps_input=QSpinBox()self.fps_input.setValue(30)# 开始/停止按钮self.btn_start=QPushButton("开始推理")self.btn_stop=QPushButton("停止推理")self.btn_reset=QPushButton("重置")self.btn_start.clicked.connect(self.start_inference)self.btn_stop.clicked.connect(self.stop_inference)self.btn_reset.clicked.connect(self.reset_tracker)# 添加控件到布局control_layout.addWidget(self.video_label)control_layout.addWidget(self.video_input)control_layout.addWidget(self.btn_select_video)control_layout.addWidget(self.model_label)control_layout.addWidget(self.model_combo)control_layout.addWidget(self.conf_slider)control_layout.addWidget(self.conf_label)control_layout.addWidget(self.iou_slider)control_layout.addWidget(self.iou_label)control_layout.addWidget(self.device_combo)control_layout.addWidget(self.fps_input)control_layout.addWidget(self.show_labels)control_layout.addWidget(self.show_speed)control_layout.addWidget(self.save_results)control_layout.addWidget(self.save_frames)control_layout.addWidget(self.show_mask)control_layout.addWidget(self.btn_start)control_layout.addWidget(self.btn_stop)control_layout.addWidget(self.btn_reset)# 右侧视频显示区self.video_label=QLabel()self.video_label.setAlignment(Qt.AlignCenter)self.video_label.setMinimumSize(800,600)self.video_label.setStyleSheet("background:#f0f0f0; border:1px solid #ccc;")# 日志区域self.log_text=QTextEdit()self.log_text.setReadOnly(True)self.log_text.setMaximumHeight(100)layout.addWidget(control_panel)layout.addWidget(self.video_label)layout.addWidget(self.log_text)defselect_video(self):path,_=QFileDialog.getOpenFileName(self,"选择视频","","Video Files (*.mp4 *.avi)")ifpath:self.video_input.setText(path)self.current_video=pathdefchange_model(self):model_name=self.model_combo.currentText()self.tracker=CarSpeedTracker(f"weights/{model_name}")defchange_device(self):device="cuda"ifself.device_combo.currentText()=="GPU"else"cpu"self.tracker.device=devicedefstart_inference(self):ifnotself.current_video:self.log_text.append("❌ 请先选择视频!")returnself.cap=cv2.VideoCapture(self.current_video)self.is_running=Trueself.timer.start(30)self.log_text.append("▶️ 开始推理...")defstop_inference(self):self.is_running=Falseself.timer.stop()ifself.cap:self.cap.release()self.log_text.append("⏹️ 停止推理")defreset_tracker(self):self.tracker=CarSpeedTracker()self.log_text.append("🔄 跟踪器已重置")defupdate_frame(self):ifnotself.capornotself.is_running:returnret,frame=self.cap.read()ifnotret:self.stop_inference()returnconf=self.conf_slider.value()/100.0iou=self.iou_slider.value()/100.0result_frame,tracks,speeds=self.tracker.detect_and_track(frame,conf=conf,iou=iou)# 更新 UIrgb_image=cv2.cvtColor(result_frame,cv2.COLOR_BGR2RGB)h,w,ch=rgb_image.shape bytes_per_line=ch*w qt_image=QImage(rgb_image.data,w,h,bytes_per_line,QImage.Format_RGB888)self.video_label.setPixmap(QPixmap.fromImage(qt_image).scaled(self.video_label.width(),self.video_label.height(),Qt.KeepAspectRatio,Qt.SmoothTransformation))# 更新日志self.log_text.append(f"📊 当前帧数:{int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))}")🚀 运行方式
python GUI.py✅ 功能亮点
| 功能 | 说明 |
|---|---|
| 🎯 多目标跟踪 | 每辆车分配唯一 ID,持续追踪 |
| 🚗 车速计算 | 基于帧间位移估算速度(需校准 GSD) |
| ⚙️ 参数自定义 | 置信度、IOU、设备、模型均可调节 |
| 📊 可视化界面 | 实时显示速度、轨迹、标签 |
| 📁 模块化设计 | 支持任意 YOLO 权重文件加载 |
| 🌐 GPU 加速 | 自动启用 CUDA 提升性能 |