1. 项目概述
这个基于YOLOv8的交通车辆检测系统是我最近完成的一个实战项目,它能够实时识别12种常见车型,包括轿车、卡车、巴士等。作为一个完整的端到端解决方案,项目不仅包含了训练好的模型权重,还配备了PyQt5开发的图形界面,让没有编程基础的用户也能轻松使用。
在实际测试中,系统在1080p视频上的检测速度达到了45FPS(使用RTX 3060显卡),准确率mAP@0.5达到92.3%。最让我满意的是它的易用性——从数据标注到模型训练,再到最终部署,整个流程都做了完整封装,真正做到了"开箱即用"。
2. 系统架构设计
2.1 技术选型考量
选择YOLOv8作为核心检测模型主要基于三个考量:
- 推理速度:相比YOLOv5,v8在保持相近精度的情况下,推理速度提升了15-20%
- 部署便利:原生支持ONNX/TensorRT导出,方便后续边缘设备部署
- 训练效率:新的损失函数设计使模型收敛更快,我们实测训练时间缩短了约30%
PyQt5作为GUI框架的优势在于:
- 跨平台支持(Windows/Linux/macOS)
- 丰富的UI组件库
- 与Python生态无缝集成
2.2 系统工作流程
整个系统的工作流程可以分为四个核心环节:
输入处理层:
- 支持多种输入源:图片(JPG/PNG)、视频(MP4/AVI)、RTSP流、USB摄像头
- 自动分辨率适配(480p-4K)
- 帧率控制(15-60FPS可调)
推理引擎层:
- 基于YOLOv8s(平衡速度和精度)
- 动态batch处理(1-16可调)
- 后处理优化(NMS阈值0.45)
结果可视化层:
- 实时绘制检测框(颜色按车型分类)
- 显示置信度分数
- 叠加FPS计数器
输出存储层:
- 图片结果保存(原始图+标注图)
- 视频导出(带检测结果)
- JSON格式的检测日志
3. 数据集与模型训练
3.1 数据准备
我们收集了约15,000张包含12类车辆的标注图像,数据分布如下:
| 车辆类型 | 训练集 | 验证集 | 测试集 |
|---|---|---|---|
| 轿车 | 3200 | 400 | 400 |
| SUV | 2800 | 350 | 350 |
| 卡车 | 2500 | 300 | 300 |
| 巴士 | 1800 | 200 | 200 |
| ... | ... | ... | ... |
数据增强策略:
- 基础增强:随机翻转(p=0.5)、色彩抖动(±20%)
- 高级增强:Mosaic(p=0.2)、MixUp(p=0.1)
- 特殊处理:模拟雨天/雾天效果(p=0.05)
3.2 模型训练细节
训练配置参数:
# yolov8s-vehicle.yaml lr0: 0.01 lrf: 0.01 momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3 warmup_momentum: 0.8 box: 7.5 cls: 0.5 dfl: 1.5关键训练命令:
yolo detect train data=vehicle.yaml model=yolov8s.yaml epochs=100 imgsz=640 batch=32 device=0注意:建议使用至少11GB显存的GPU进行训练,batch_size可适当调整。我们在RTX 3090上完成100个epoch训练约需6小时。
3.3 训练结果分析
训练过程中的关键指标变化:
| Epoch | box_loss | cls_loss | dfl_loss | mAP@0.5 |
|---|---|---|---|---|
| 10 | 1.253 | 0.892 | 1.567 | 0.684 |
| 30 | 0.745 | 0.453 | 1.124 | 0.823 |
| 50 | 0.532 | 0.287 | 0.893 | 0.887 |
| 80 | 0.421 | 0.198 | 0.765 | 0.915 |
| 100 | 0.387 | 0.173 | 0.724 | 0.923 |
从损失曲线可以看出,模型在50个epoch后进入平稳期,此时可以提前终止训练(early stopping)以节省时间。
4. PyQt5界面开发
4.1 界面功能设计
主界面包含以下核心功能区:
输入选择区:
- 文件选择按钮(图片/视频)
- 摄像头选择下拉框
- 文件夹批量处理选项
显示区:
- 原始视频流显示
- 检测结果叠加显示
- 实时FPS计数器
控制区:
- 开始/暂停/停止按钮
- 置信度阈值滑块(0.1-0.9)
- 保存结果复选框
信息区:
- 当前检测车辆统计
- 类别分布饼图
- 日志输出窗口
4.2 关键技术实现
多线程处理架构:
class DetectionThread(QThread): def __init__(self): super().__init__() self.model = YOLO('weights/best.pt') def run(self): while self.running: frame = self.get_frame() results = self.model(frame, conf=0.5) self.send_result.emit(results)信号槽通信机制:
class MainWindow(QMainWindow): def __init__(self): self.det_thread = DetectionThread() self.det_thread.send_result.connect(self.update_ui) def update_ui(self, results): # 更新界面显示 self.display_image(results.plot())经验分享:PyQt5中处理视频流时一定要使用QThread,否则界面会卡顿。我们实测多线程方案可以将界面响应速度提升5-8倍。
5. 部署与优化
5.1 不同平台性能对比
我们在多种硬件平台上测试了系统性能:
| 平台 | 分辨率 | FPS | 显存占用 |
|---|---|---|---|
| RTX 4090 | 1080p | 68 | 2.3GB |
| RTX 3060 | 1080p | 45 | 1.8GB |
| Jetson Xavier NX | 720p | 22 | 1.2GB |
| Raspberry Pi 4B | 480p | 3.5 | - |
5.2 模型优化技巧
- TensorRT加速:
yolo export model=weights/best.pt format=engine device=0转换后推理速度可提升30-50%
- 量化压缩:
model.quantize(data='vehicle.yaml', imgsz=640, epochs=10)8-bit量化后模型大小减少4倍,速度提升20%
- 剪枝优化:
from torch_pruner import L1NormPruner pruner = L1NormPruner(model, 0.3) pruner.apply()适度剪枝可减少30%计算量,精度损失<2%
5.3 常见问题解决
问题1:检测框闪烁不稳定
- 解决方案:添加轨迹平滑滤波(α=0.3的指数加权平均)
问题2:小车辆漏检
- 解决方案:修改anchors设置,增加小目标检测层
问题3:类别混淆(如SUV/轿车)
- 解决方案:在混淆矩阵分析后,针对性增加难例样本
6. 实际应用案例
6.1 交通流量统计
我们在某城市路口部署了该系统,实现了:
- 实时车流量计数(精度>95%)
- 车型分类统计
- 高峰时段分析
核心统计代码:
def count_vehicles(results): counts = {class_name:0 for class_name in CLASS_NAMES} for box in results.boxes: class_id = int(box.cls) counts[CLASS_NAMES[class_id]] += 1 return counts6.2 违章检测扩展
基于现有系统,我们增加了:
- 违章停车检测(区域入侵分析)
- 车牌模糊识别(配合OCR模块)
- 行车轨迹追踪(Kalman滤波)
实施建议:可以先从基础车型检测开始,逐步添加扩展功能模块,避免一次性开发复杂度太高。
7. 项目二次开发指南
7.1 如何添加新车型
- 收集新车型样本(建议每类至少500张)
- 使用LabelImg工具标注(YOLO格式)
- 修改data/vehicle.yaml中的nc和names参数
- 微调模型(建议冻结backbone训练):
yolo detect train data=vehicle.yaml model=weights/best.pt epochs=50 freeze=[0,1,2]7.2 界面定制修改
常用定制点:
- 修改UI主题:编辑qss样式表
- 添加新功能:继承QMainWindow类扩展
- 多语言支持:使用Qt Linguist工具
7.3 边缘设备部署
RK3588部署示例:
# 转换RKNN模型 python export.py --weights best.pt --rknn --platform rk3588 # C++推理代码 #include <rknn_api.h> rknn_input inputs[1]; inputs[0].index = 0; inputs[0].buf = image_data; rknn_output outputs[3]; RKNN_API rknn_run(ctx, inputs, 1, outputs, 3);8. 完整项目结构说明
项目目录结构:
vehicle_detection/ ├── data/ │ ├── images/ # 原始图像 │ ├── labels/ # YOLO格式标注 │ └── vehicle.yaml # 数据集配置 ├── models/ │ ├── yolov8s.yaml # 模型结构 │ └── best.pt # 训练权重 ├── utils/ │ ├── augment.py # 数据增强 │ └── metrics.py # 评估指标 ├── ui/ │ ├── main_window.py # 主界面 │ └── resources/ # 图标资源 ├── detect.py # 推理脚本 ├── train.py # 训练脚本 └── requirements.txt # 依赖库安装步骤:
# 创建conda环境 conda create -n vehicle python=3.8 conda activate vehicle # 安装依赖 pip install -r requirements.txt # 测试运行 python detect.py --source test.jpg --weights models/best.pt在项目开发过程中,有几个关键点值得特别注意:首先是数据质量,我们发现清洗后的数据比单纯增加数据量更有效;其次是模型大小选择,YOLOv8s在精度和速度间取得了很好平衡;最后是界面响应性设计,合理的多线程架构能显著提升用户体验。