云计算百科
云计算领域专业知识百科平台

基于深度学习的交通标志与行人车辆检测系统

基于深度学习的交通标志与行人车辆检测系统 —— 功能与技术点详解

一个把「YOLOv8 目标检测」和「PyQt5 桌面界面」完整打通的实战项目:既能检测交通标志,也能识别行人与车辆,支持图片、文件夹批量、视频、摄像头四种输入方式。


通过网盘分享的文件:交通标志与行人车辆检测系统8.zip
链接: https://pan.baidu.com/s/1SzfiXqEh0k8bRzFXYU0OyQ?pwd=ek4j 提取码: ek4j
–来自百度网盘超级会员v7的分享

一、在这里插入图片描述

在这里插入图片描述

项目背景

交通场景下的感知任务是计算机视觉最经典的应用之一:交通信号灯、限速标志、人行横道,以及行人、公交车、汽车、卡车等目标,都是自动驾驶与智能交通的基础感知对象。

本项目实现了一套开箱即用的桌面级检测系统,把训练好的 YOLOv8 模型封装进图形界面,让不懂编程的使用者也能直接拖入图片或视频完成检测,同时保留完整的参数调节与结果导出能力。


二、系统功能一览

2.1 检测类别(共 9 类)

ID英文名中文名
0 Trafic Light Signal 交通信号灯
1 Stop Signal 停止信号
2 Speedlimit Signal 限速信号
3 Crosswalk Signal 人行横道信号
4 Crosswalk 人行横道
5 Pedestrian 行人
6 Bus 公交车
7 Car 汽车
8 Truck 卡车

2.2 核心功能

功能说明
单张图片检测 支持 jpg / jpeg / png / bmp,检测完成后在界面展示带框结果
文件夹批量检测 选中整个文件夹,自动遍历所有图片逐张检测,结果追加进结果表格
视频文件检测 支持 avi / mp4 / wmv / mkv,逐帧检测并实时刷新预览画面
摄像头实时检测 调用本机摄像头(默认设备 0),实时画面 + 实时检测
检测参数可调 置信度阈值、交并比阈值(IOU)界面实时调节,即时生效
标签显示开关 可一键切换「显示类别与置信度」或「只画检测框」
目标逐个查看 下拉框选择「全部」或某个具体目标,单独查看该目标的框与坐标
结果信息表格 序号、文件路径、类别、置信度、坐标位置,逐条列出
结果导出 图片结果写入 save_data,视频结果导出为带检测框的 avi 文件
训练脚本 提供 train.py,可基于自有数据集重新训练模型

三、技术架构

整个系统可以划分为三层,层次清晰、职责单一:

┌─────────────────────────────────────────────┐
│ 界面层(PyQt5) │
│ UiMain.py / style.css / 各类控件与信号槽 │
├─────────────────────────────────────────────┤
│ 逻辑层(MainProgram.py) │
│ 业务调度:读图/读视频/摄像头、参数管理、 │
│ 结果展示、结果保存、多线程 │
├─────────────────────────────────────────────┤
│ 推理层(ultralytics + PyTorch) │
│ YOLOv8 模型加载与推理,输出 boxes 结果 │
├─────────────────────────────────────────────┤
│ 工具层(detect_tools.py / Config.py) │
│ 图像格式转换、绘制、路径读取、全局配置 │
└─────────────────────────────────────────────┘

  • 界面层:由 Qt Designer 设计 .ui 文件并生成 UiMain.py,通过 style.css 做 QSS 样式美化。
  • 逻辑层:MainProgram.py 中的 MainWindow 类负责把界面事件与推理逻辑串起来。
  • 推理层:使用 ultralytics 的 YOLO 接口加载 models/best.pt 完成推理。
  • 工具层:Config.py 集中管理模型路径、类别名称、保存路径;detect_tools.py 提供绘图与格式转换等通用函数。

四、核心技术点拆解

4.1 目标检测:YOLOv8 单阶段检测

项目使用 YOLOv8(ultralytics 8.0.199)作为检测模型,任务类型为 detect:

# MainProgram.py
from ultralytics import YOLO
self.model = YOLO(Config.model_path, task='detect')

加载模型后,一次推理即可拿到所有目标框。结果从 results 对象中按字段取出,结构非常清晰:

results = self.model(img_path, conf=self.conf_thres, iou=self.iou_thres)[0]

location_list = results.boxes.xyxy.tolist() # 每个目标的 [x1, y1, x2, y2]
cls_list = results.boxes.cls.tolist() # 每个目标的类别 ID
conf_list = results.boxes.conf.tolist() # 每个目标的置信度

这种「一次前向 + 三个并行列表」的组织方式,为后续界面展示提供了极大便利。

4.2 模型训练策略

模型基于 YOLOv8 架构训练,关键超参数如下(来自训练结果目录中的配置记录):

参数取值说明
task detect 目标检测任务
epochs 50 训练轮数
batch 4 批大小(显存/内存友好)
imgsz 640 输入分辨率
optimizer SGD 优化器
lr0 / lrf 0.01 / 0.01 初始学习率 / 最终学习率系数
momentum 0.937 动量
weight_decay 0.0005 权重衰减
warmup_epochs 3.0 预热轮数
close_mosaic 10 最后 10 轮关闭 Mosaic 增强
fliplr 0.5 随机水平翻转增强
mosaic 1.0 Mosaic 数据增强
erasing 0.4 随机擦除增强
degrees / shear / perspective 0 / 0 / 0 未启用旋转、错切、透视增强

几个值得注意的工程取向:

  • 数据增强适中:启用了 Mosaic、水平翻转、HSV 色彩扰动,但关闭了旋转、透视等强几何变换——交通场景的目标朝向相对固定,过强的几何增强反而会引入噪声。
  • 最后阶段关闭 Mosaic:close_mosaic=10 让模型在训练末期回归真实分布,提升最终精度。
  • batch=4 与 workers=0:典型的「消费级显卡 / CPU 环境也能跑」的保守配置。

训练结果(损失曲线、PR 曲线、混淆矩阵、验证集预测可视化等)全部保存在 models/exp27 目录中,可直接用于分析模型表现。

4.3 PyQt5 界面:Qt Designer + QSS

界面采用「可视化设计 + 代码生成」的方式:

  • .ui 文件由 Qt Designer 设计,UiMain.py 由它生成;
  • 业务代码通过多重继承方式复用生成的界面类:

class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self) # 装载设计好的界面
self.initMain() # 业务初始化
self.signalconnect() # 绑定信号与槽

  • 外观通过外部 QSS 文件统一管理,样式与代码解耦:

style_file = 'UIProgram/style.css'
self.setStyleSheet(QSSLoader.read_qss_file(style_file))

这种写法的好处是:改界面不用动业务逻辑,改样式不用重新生成界面代码。

4.4 信号与槽:界面响应的事件驱动模型

所有交互都通过 Qt 的信号槽机制绑定,一处集中注册,结构一目了然:

def signalconnect(self):
self.PicBtn.clicked.connect(self.open_img) # 打开图片
self.FilesBtn.clicked.connect(self.detact_batch_imgs) # 批量检测
self.VideoBtn.clicked.connect(self.vedio_show) # 打开视频
self.CapBtn.clicked.connect(self.camera_show) # 打开摄像头
self.SaveBtn.clicked.connect(self.save_detect_video) # 保存结果
self.ExitBtn.clicked.connect(QCoreApplication.quit) # 退出
self.comboBox.activated.connect(self.combox_change) # 目标切换

4.5 多线程:让视频保存不再卡死界面

视频逐帧推理是一个耗时操作,如果直接放在主线程里,界面会「未响应」。项目用 QThread 把它挪到后台线程,并通过信号回传进度:

class btn2Thread(QThread):
update_ui_signal = pyqtSignal(int, int) # 当前帧数, 总帧数

def run(self):
while cap.isOpened() and self.is_running:
ret, frame = cap.read()
results = self.model(frame, conf=self.conf, iou=self.iou)[0]
out.write(results.plot())
self.update_ui_signal.emit(cur_num, total) # 上报进度

主线程收到信号后更新进度条:

self.btn2Thread_object.update_ui_signal.connect(self.update_process_bar)

同时还设置了 is_running 标志位,支持用户中途取消保存(关闭进度条窗口即终止线程),这是一个很实用的健壮性设计。

4.6 图像渲染:从 OpenCV 到 Qt 的无缝转换

OpenCV 使用 BGR 通道顺序、numpy 数组存储;Qt 需要 QImage 才能显示。项目封装了标准转换函数:

def cvimg_to_qpiximg(cvimg):
height, width, depth = cvimg.shape
cvimg = cv2.cvtColor(cvimg, cv2.COLOR_BGR2RGB) # BGR → RGB
qimg = QImage(cvimg.data, width, height, width * depth, QImage.Format_RGB888)
return QPixmap(qimg)

同时,为了让不同比例的图片都完整显示在固定大小的显示区内,实现了等比自适应缩放:

def get_resize_size(self, img):
img_height, img_width, _ = img.shape
ratio = img_width / img_height
if ratio >= self.show_width / self.show_height:
self.img_width = self.show_width
self.img_height = int(self.img_width / ratio)
else:
self.img_height = self.show_height
self.img_width = int(self.img_height * ratio)
return self.img_width, self.img_height

4.7 中文标签绘制:绕开 OpenCV 的短板

OpenCV 的 cv2.putText 不支持中文,直接写会显示成「???」。项目的做法是交给 PIL 绘制:

def drawRectBox(image, rect, addText, fontC, color):
cv2.rectangle(image, (rect[0], rect[1]), (rect[2], rect[3]), color, 2)
cv2.rectangle(image, (rect[0] – 1, rect[1] – 25), (rect[0] + 60, rect[1]), color, –1)
img = Image.fromarray(image)
draw = ImageDraw.Draw(img)
draw.text((rect[0] + 2, rect[1] – 27), addText, (255, 255, 255), font=fontC)
return np.array(img)

字体在程序启动时加载一次并复用,避免每帧都读字体文件:

from PIL import ImageFont
self.fontC = ImageFont.truetype("Font/platech.ttf", 25, 0)

4.8 参数动态调节:改阈值即时重检

置信度和 IOU 阈值不是「设完重启才生效」,而是改动即触发重检,交互体验更好:

def update_conf_thres(self, value):
self.conf_thres = value
if hasattr(self, 'model'):
self.model.conf = value
if hasattr(self, 'org_img'):
self.detect_current_image() # 立即用新阈值重新检测当前图片

滑块滚动过程中就能直观看到「哪些目标被过滤掉了」,非常适合做阈值调优演示。

4.9 中文路径读取:cv2.imread 的隐藏坑

cv2.imread 在中文路径下会静默失败(返回 None)。项目改用 imdecode 方案规避:

def img_cvread(path):
# 读取含中文名的图片文件
img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_COLOR)
return img

在本机实测中,项目位于含中文的目录下依然可以正常运行。

4.10 模型预热与设备自动选择

两个容易被忽略但很影响体验的细节:

设备自动选择——有 GPU 用 GPU,没有就退回 CPU:

self.device = 0 if torch.cuda.is_available() else 'cpu'

模型预热——启动时先用一张小图跑一次推理,把算子/runtime 初始化提前完成,避免用户点第一张图时卡顿:

self.model = YOLO(Config.model_path, task='detect')
self.model(np.zeros((48, 48, 3)), device=self.device) # 预先加载推理模型


五、界面交互设计

界面整体分为左右两大区域,符合「左边看结果、右边看数据」的使用习惯:

  • 左侧检测显示区:展示原图 / 检测结果图 / 视频帧,中央自适应缩放。
  • 右侧检测结果区:
    • 顶部为检测参数设置(标签开关、置信度阈值、交并比阈值);
    • 中部为检测信息面板(目标数目、目标选择下拉框、类型、置信度、xmin/ymin/xmax/ymax、用时);
    • 底部为结果表格(序号 / 文件路径 / 类别 / 置信度 / 坐标位置)。
  • 底部操作栏:打开图片、打开文件夹、打开视频、打开摄像头、保存、退出。

批量检测时表格会自动滚动到最新一行,并通过 QApplication.processEvents() 实时刷新界面,让用户看到「逐张处理」的过程而不是假死。


六、性能实测

在纯 CPU 环境下(不依赖显卡)实测:

指标实测值
单张图片推理耗时 约 58 ~ 71 ms(640×640 输入)
前处理 约 1 ~ 12 ms
后处理 约 1 ms
运行设备 CPU(torch.cuda.is_available() 为 False 时自动回退)

也就是说,CPU 下单张图片约 0.06 ~ 0.07 秒即可完成检测,实时视频与摄像头场景也完全可用(30 FPS 视频需约 33 ms/帧,实测接近该量级)。若配备 GPU 并安装 CUDA 版 PyTorch,速度还可进一步提升。


七、工程化细节与踩坑记录

问题现象解决方式
模型加载失败 ModuleNotFoundError: No module named 'dill' best.pt 使用 dill 序列化,需在虚拟环境中 pip install dill
中文路径读图失败 cv2.imread 返回 None 改用 cv2.imdecode + np.fromfile
中文标签乱码 cv2.putText 显示问号 改用 PIL ImageDraw + TrueType 字体绘制
视频保存时界面卡死 主线程被推理阻塞 用 QThread 后台推理 + 信号回传进度
换机器后训练报错 dataset.yaml 里是绝对路径 训练前改为自己的数据集路径
ultralytics 自动装依赖装错环境 dill 装到系统 Python 而非虚拟环境 手动在虚拟环境中 pip install dill

八、可扩展方向

  • 模型升级:替换为 YOLOv8s/m/l 等更大规模模型,在精度与速度之间重新权衡。
  • 目标跟踪:接入 botsort / bytetrack,为视频中的目标分配 ID,实现轨迹跟踪与计数。
  • 性能加速:导出 ONNX / TensorRT / OpenVINO 格式,进一步提升推理速度。
  • 业务功能扩展:加入越线检测、区域入侵、车流量统计等交通事件判定。
  • 部署形态扩展:封装为 Web 服务(FastAPI + 前端),或用 PyInstaller 打包成免安装 exe。

  • 九、总结

    这个项目最大的价值在于闭环完整:从数据准备、模型训练(train.py + dataset.yaml),到推理封装(ultralytics + best.pt),再到界面交互(PyQt5)、多线程优化、结果导出,形成了一条可以直接交付给使用者的完整链路。

    技术上它覆盖了几个非常实用的工程要点:

    • 单阶段检测器的一次前向多字段解析;
    • Qt 界面与业务逻辑的解耦(Qt Designer + QSS + 信号槽);
    • 耗时任务的后台线程化与进度反馈;
    • 跨库协作时的格式转换(OpenCV ↔ Qt ↔ PIL);
    • 中文路径、中文标签这类「国产环境下的经典坑」的规避方案。

    对于想入门「深度学习 + 桌面应用」落地的开发者来说,这是一个很好的参考样本。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 基于深度学习的交通标志与行人车辆检测系统
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!