ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv8的交通信号灯识别与通行规则判定系统实践

基于YOLOv8的交通信号灯识别与通行规则判定系统实践 简介本资源是一套基于YOLOv8实现的路口交通信号灯通行规则识别系统面向人工智能、自动化、电子信息等专业的在校学生、教师及工程技术人员解决实际交通场景中红绿灯状态判别与通行逻辑解析的核心问题适用于毕业设计、课程设计、项目立项演示及深度学习入门进阶实践。压缩包共18个文件含11个Python源码覆盖数据处理、目标检测、结果可视化与规则判断全流程、2个配置与依赖说明文件config.yaml、requirements.txt、2个效果示意图PNG、1个README文档及基础工具脚本整体仅706KB轻量易部署。已有54人下载学习资源源自高分结题项目答辩95分代码经实测可直接运行配套完整技术文档与模块化目录结构含detect/classify/recognize等清晰子模块便于理解YOLOv8在交通视觉任务中的定制化应用与二次开发。 去年开始折腾一套基于 YOLOv8 的路口交通信号灯通行规则识别系统从数据标注、模型训练到规则判定逻辑再到最后尝试部署到嵌入式设备前后花了几个月。这个项目既不是那种玩具级 demo也不是纯学术的论文复现它要解决的核心问题有两个一是准确检测路口信号灯并识别当前灯色二是根据灯色和车道的几何关系推理出“当前车道能不能走”的通行规则。源码、模型权重、数据集整理和文档我都打包好了下面把整个项目的技术路线、踩坑经历和实施细节完整捋一遍。这套方案真正落地会牵扯到很多比“目标检测”本身更磨人的细节比如夜间灯晕、直行与左转车道对应不同信号灯组、倒计时数字识别、信号灯闪烁状态等。无论你是要做课程设计、毕业选题还是想把这个方向往辅助驾驶项目上靠这篇内容都值得完整看一遍我会把从零到一到最后的规则判定、模型压缩部署、答辩汇报要点全部讲透。1. 信号灯识别真正难在哪一个目标检测任务背后的隐藏挑战很多人以为交通信号灯识别就是一个“用目标检测框出灯再分类颜色”的任务。真做起来才发现这个任务的难点分布和常规目标检测完全不同。1.1 先厘清“识别灯”和“理解通行规则”是两码事从项目标题就能看出来这不是单纯的信号灯目标检测最终交付物是“通行规则识别模型”。也就是说模型不仅要告诉系统“画面里有一组红灯”还要结合当前车辆所在的车道告诉系统“当前车道对应的灯组是哪一个”“此时能否通行”。我把整体方案拆成了四个模块信号灯目标检测用 YOLOv8 定位画面中的信号灯组并识别灯色状态红、黄、绿、闪烁、熄灭。车道与灯组的对应关系利用检测框的几何坐标和车道线先验信息建立“当前车道—灯组”的空间关联。时序状态确认单帧的判断并不可靠需要通过连续帧的状态机或投票机制消除跳变和误检。通行规则输出结合灯色和车辆位置输出“可通行 / 减速观察 / 停车等待”三类驾驶建议。这个架构下YOLOv8 只是第一步。对初学者来说最容易掉进去的坑就是模型检测 mAP 很高但下到路口实测时系统根本不知道“这个红灯到底管不管我这条车道”。所以项目资料里我把“几何匹配 状态机”这部分单独做了详细文档它的复杂程度不亚于模型本身。1.2 和普通目标检测任务相比信号灯检测的差异化难点信号灯属于典型的“小目标、极端光照、密集场景”目标常规目标检测的很多经验在这里并不适用。目标尺寸足够小。在 1080P 图像中一组信号灯的整体高度往往只有 30~50 像素单个灯体可能只有 15~20 像素。YOLOv8 的下采样倍数最高达到 32 倍小目标在深层的特征图只有 1~2 个像素响应极易漏检。为解决这个问题我在训练时使用了 1280 的输入分辨率同时保留了 P2 层输出即 4 倍下采样特征层。这部分会在后面章节详细展开。光照变化极端。白天逆光时信号灯可能整体处于过曝边缘夜间灯体亮起后周围会形成大面积光晕且灯色会“染”到周围环境比如红灯会把附近的路面、车辆染红。这种环境导致模型容易学到错误线索用白天数据训出来的模型一到夜间测试mAP 直接断崖式下跌。颜色表达不稳定。不同厂家、不同批次的 LED 信号灯颜色波长并不完全一致再加上相机白平衡、AWB 的影响同一个红灯在不同设备上拍出来可能是偏橙红的。这意味着不能完全依赖“像素 HSV 阈值分割”这样的传统方案必须让模型自己去学习灯色的语义特征。2. 数据集与标注精度上限早在标注阶段就已经决定了模型最终能到多少精度数据比模型结构的影响更大。这句话在信号灯任务上体现得格外明显。2.1 数据来源建议公开数据集打底自采数据补场景我用了两个层面的数据公开数据集包括 Bosch Small Traffic Lights Dataset、LISA Traffic Light Dataset、以及部分从 OpenImages 里筛选出的信号灯数据。其中 Bosch 数据集主要是欧洲城市场景灯体形态和国内有一定差异只用来做预训练和基础能力打底。自建数据用行车记录仪在市区、城郊、夜间、雨天等场景采集了大量路口视频逐帧抽帧后筛选并标注。实测下来自采数据至少要占到总数据量的 60% 以上模型在本地场景的泛化能力才有保障。如果你只是做课程项目公开数据集完全够用但要声称“可落地”自采数据必不可少。我的最终数据集构成大致如下场景图片数量标注框数量备注白天晴天32008400含直行、左转、右转、掉头灯组白天逆光9002100最难标注、最容易漏检的场景夜间14003600含灯晕、过曝、反光干扰雨天/雾天5001200镜头脏污、模糊总计600015300按 8:2 划分训练集/验证集标注框统计下来每张图平均只有 2.5 个目标。和 COCO 那种每张图七八个目标不一样信号灯图像的负样本信息量更大背景干扰也更复杂所以抽帧时我特意保留了没有信号灯的路口帧作为负样本参与训练这一招对降低误检率很有效。2.2 标注类别怎么定颜色、状态、方向都要管信号灯标注的类别设计有两种流派一是只标“灯组”整体颜色判别交给后处理二是直接把“红、黄、绿、红左、绿直、绿左”等细类都定义出来。我最终采用的是“灯体级 颜色级”混合标注方案类别列表如下red_common圆盘红灯green_common圆盘绿灯yellow_common圆盘黄灯red_left左转箭头红灯green_left左转箭头绿灯red_right右转箭头红灯green_right右转箭头绿灯yellow_arrow箭头黄灯green_walk行人绿灯部分路口联动参考red_walk行人红灯countdown倒计时数字后续可选识别每个信号灯组的每个发光单元都单独标注一个框而不是把整个灯板框住。原因很简单下层的通行规则判定需要知道具体是哪个方向的灯在亮如果只标灯组整体颜色和方向的判断就要靠后处理裁剪再分类流程复杂且极易受曝光影响。标注工具我用的是 LabelImg 和 X-AnyLabeling前者轻量后者支持半自动辅助标注。6000 张图、15300 个框单人标注大概用了两个周末如果时间紧可以先用 X-AnyLabeling 的自动检测模型预标注再手动修正效率能提升一半以上。2.3 标注一致性比数量更关键的一件事这个坑我必须单独拎出来说多人协作标注时标注框的边界定义必须统一。比如“灯体框”到底是从发光区域边缘开始还是包含外部不亮的灯壳红色箭头灯在夜间有明显的漫反射框要不要包含光晕这些如果不统一训练出来的模型边框回归会很不稳定Loss 里 bbox 那一项永远降不下去。我的规定是只框发光区域不框灯壳。光晕严重时以核心发光体为准宁小勿大。不包含倒计时数字倒计时数字单独作为一类。灯被遮挡超过 1/3 时不标注。这些规则写进了数据说明文档后续如果有人要扩展数据集不会出现“前面的人标 A 标准、后面的人标 B 标准”的混乱。3. 基于 YOLOv8 的模型选型与结构取舍3.1 为什么是 YOLOv8而不是 Faster R-CNN 或 SSD最初我也考虑过 Faster R-CNN它在小目标上的理论精度确实不错但实测在 1080P 视频流上单帧推理要 100ms 以上根本没法满足路口实时性的需求。SSD 的精度又不太够特别是小目标召回率低。YOLOv8 相比前代 YOLOv5改进点在于 C2f 结构带来的梯度流优化以及 Anchor-Free 检测头省去了大量锚框调参工作在同等算力下精度和速度平衡得更好。最终落地用的是 YOLOv8s输入分辨率 1280x1280。用 NVIDIA GTX 1660 Ti 推理TensorRT FP16 下单帧耗时约 18ms算上前后处理能稳定跑 30FPS满足实时要求。如果算力更紧张可以换 YOLOv8nmAP 会掉大概 2~3 个点但速度能提升一小半。3.2 模型结构上的关键调整针对小目标的 P2 输出YOLOv8 默认从 P38 倍下采样、P416 倍、P532 倍三个尺度输出预测。但前面说过信号灯在图像中往往只有十几个像素8 倍下采样后只剩 1~2 个像素检测头很难有效匹配。我的做法是在 YOLOv8s 的基础上增加了 P2 输出层4 倍下采样也就是把 C2f 的浅层特征直接送入检测头。这样修改会增加大约 15% 的计算量但小目标的召回率提升非常明显。修改方式不复杂在 yaml 配置文件里调整检测头的 from 和 anchors 相关部分并同步调整 stride 列表。P2 层引入后小目标漏检率大约下降了 20%。如果你的数据集里灯体特别小这一步一定不要省。3.3 训练细节1280 分辨率、多尺度、Mosaic 增强训练参数我记录一份方便你直接复现参数数值说明输入尺寸1280x1280保留小目标细节显存不足可降到 960Batch Size161660 Ti 的 6GB 显存梯度累积实现Epochs300早停 patience50OptimizerSGDlr00.01, lrf0.01, momentum0.937数据增强Mosaic1.0, MixUp0.1, HSV 微调夜间数据增强幅度需保守预训练权重YOLOv8s COCO 权重迁移学习收敛更快特别说一下 Mosaic 增强。YOLOv8 默认 Mosaic 概率是 1.0也就是每张训练图都由 4 张图拼接而成。在常规目标检测里这是好事能大幅提升背景多样性但在信号灯场景下Mosaic 会把 4 个不同光照环境的路口拼在一起产生大量不真实的光影组合而且小目标被裁剪的概率更高。后来我把 Mosaic 概率降到 0.5关闭了 MixUp验证集 mAP 反而涨了 1.5 个点。夜间场景数据增强要格外慎重。如果对图像做强 HSV 通道扰动可能把夜间红灯变成橙红色、绿灯变成青色这会让模型学到错误颜色分布。所以我只用轻度亮度抖动色相扰动幅度控制在 ±5 以内。4. 训练全流程与损失函数曲线排查4.1 环境配置CUDA、PyTorch、ultralytics 版本对齐环境配置是很多初学者第一道坎。我的推荐组合Python 3.10 / 3.11PyTorch 2.1.2 CUDA 11.8ultralytics 8.1.0OpenCV 4.6注意PyTorch 2.13 目前并不存在如果你在某个教程里看到这个版本号大概率是写错了。安装时直接到 PyTorch 官网选对应的 CUDA 版本即可不要盲目追求最新版。1660 Ti 的 6GB 显存跑 1280 分辨率是比较吃力的我用了梯度累积accumulate4来等效放大 Batch Size。如果显存不够建议优先考虑降分辨率到 960而不是强行提升 Batch Size低分辨率带来的小目标信息损失是后期很难弥补的。4.2 训练阶段的 Loss 曲线怎么读正常和异常长得完全不一样训练时我记录了三组 Loss 曲线——box_loss边框回归、cls_loss分类、dfl_loss分布焦点损失。这是判断模型有没有学好的核心依据。正常曲线长这样box_loss 前 50 轮快速下降从 1.6 左右降到 1.0 附近之后缓慢趋平最终稳定在 0.9~1.0 区间。cls_loss 前 30 轮下降最快从 2.0 掉到 0.8 左右之后波动收窄300 轮后稳定在 0.5 上下。dfl_loss 和 box_loss 走势类似但最终值偏小一般落在 0.8 左右。如果训练集 Loss 已经降得很低、验证集 Loss 却明显反弹那就是过拟合解决方式是加大数据增强或者引入更多夜间负样本。如果三条曲线从头到尾都在高位震荡先检查标注是否错乱、数据是否加载到了重复图片再考虑调低学习率。我这次训练到 260 轮时验证集 mAP50 已经达到 0.94mAP50-95 在 0.72 左右。这个精度在信号灯任务里算是可用的但在夜间逆光场景下 mAP50-95 会掉到 0.6 以下这也是为什么后面规则判定模块不能单靠模型还要有后处理兜底。4.3 预测结果可视化只用 val 模式远远不够很多人训练完就跑一下 val 看 mAP 数字但 mAP 高不代表你在真实路口的视频里表现好。我强烈建议训练完用predict模式跑一段完整的行车记录仪视频逐帧看检测结果。我第一次就是这么发现问题的mAP 很高但视频里红绿灯切换的瞬间模型会出现连续 3~5 帧的漏检导致规则判定模块反复横跳。原因在于数据集中“灯色切换瞬间”的样本太少比如黄灯刚亮起时灯珠的亮度尚未稳定模型会误判为红灯。后来我专门从视频里抽了 300 多帧过渡状态补进训练集重新训练这个问题大幅缓解。5. 通行规则判定从“检测到灯色”到“知道该不该走”的算法设计5.1 车道与灯组的几何匹配模型输出的是所有灯组的检测框。要判断的是“当前车道能不能走”关键是把当前车道与对应的信号灯组关联起来。这里我用的是“几何先验 投影关系”的方案不依赖高精地图。前提是摄像头的安装位置固定我是把摄像头装在车内后视镜附近光轴基本水平并且假设车辆在停止线前保持直行姿态。具体步骤通过车道线检测模型或者简单的霍夫变换直线检测找到当前车道的左右边界线计算车道中心线的像素位置。对画面中所有信号灯检测框按水平位置排序。取车道上方的灯组因为信号灯一般都位于路口对面或停止线前上方所以只保留检测框中心 y 坐标在车道消失点附近、且 x 坐标和车道中心线横向偏移小于某阈值的灯组。如果同一方向同时存在“圆盘灯”和“箭头灯”优先取箭头灯因为箭头灯的控制指令更明确。一个关键细节当车辆行驶到停止线前摄像头视角和信号灯的夹角会变大透视畸变导致灯组位置发生漂移。如果匹配完全依赖固定阈值在最后几米可能出现误匹配。我的做法是引入“车辆距停止线的估计距离”作为动态缩放因子距离越近匹配搜索窗口就越大。5.2 时序状态机单帧判断不可靠的兜底方案单帧检测结果直接驱动通行决策在路口这种安全关键场景是不负责任的。我设计了一个简化的状态机状态包括未知、红灯禁止、绿灯通行、黄灯减速、闪烁警告。每次模型输出一帧检测结果先经过置信度阈值过滤红灯阈值 0.5绿灯阈值 0.45黄灯阈值 0.4再经过连续帧确认。灯色状态切换需要连续 3 帧检测到同一状态才真正切换如果中间出现一帧漏检不重置计数只是不累加。倒计时阶段如果检测到红灯变绿的前 5 帧状态机停留在“红灯禁止”避免绿灯刚亮起时立即加速的冲动。这个设计很像单片机里的按键消抖单次触发不可信连续多次触发才有效。虽然会让系统响应慢 100ms 左右但在真实道路场景下这种“迟钝”反而是安全的。5.3 夜间、逆光、灯晕干扰的规则层面应对即使模型在训练时见过夜间数据夜间灯晕依然会让检测框不稳定。我的规则层额外做了两件事一是“光晕中心回归”补偿。夜间红灯检测框可能偏向光晕中心外延导致框的中心点和真实发光点偏移。我根据灯体面积和亮度分布计算框内像素亮度的质心用质心替代检测框中心作为灯组坐标。这个技巧在夜间实测中让几何匹配的准确率提升了 10% 以上。二是“倒计时数字联动”。很多路口倒计时数字和信号灯是一起工作的当数字跳到 0 后灯色一定会切换。我用轻量 OCR或者另一个小检测模型识别倒计时数字在数字小于 3 时主动提高状态机对灯色切换的敏感度减少漏检空档。6. 从离线模型到实时部署TensorRT 加速与嵌入式落地训练好的 .pt 权重只能算“研究成果”要真正跑在车机上还要经过一系列转换和优化。6.1 模型导出与精度对齐ultralytics 框架内置了导出功能可以导出 ONNX、TensorRT、OpenVINO 等格式。我的导出流程先将 .pt 导出为 ONNXyolo export modelbest.pt formatonnx opset12再用 ONNX 导出 TensorRT enginetrtexec --onnxbest.onnx --saveEnginebest.engine --fp16导出后务必做精度对齐验证。把同一批测试图分别用 PyTorch 和 TensorRT 推理比较检测框的 IoU 和类别一致性。FP16 精度下降通常小于 0.5%如果超过 1%建议改回 FP32 或检查是否某些层在 FP16 下精度溢出。1660 Ti 上 FP16 engine 下1280x1280 输入单帧耗时约 18ms包含预处理和后处理整体能达到 30FPS。如果目标设备是 Jetson Nano 这类低算力平台建议把输入分辨率降到 960再考虑 INT8 量化。6.2 嵌入式部署的常用流程项目资料里我给了两种部署路径的完整说明第一种是 NVIDIA Jetson 系列使用 TensorRT 部署。Jetson 上的 JetPack SDK 已经包含了 TensorRT、CUDA 等组件把 PC 上生成好的 engine 直接拷贝过去不一定兼容建议在 Jetson 本机重新构建。实测在 Jetson Orin Nano 上FP16 模式可以达到 20~25FPS基本够用。第二种是瑞芯微 RK3588 / 算能 BM1684 等国产边缘平台通常需要先导出 ONNX再用厂商提供的工具链转换为 rknn / bmodel 格式。这类平台的优点是没有 NVIDIA 的授权限制价格低、供货稳定缺点是工具链还不够成熟某些算子不支持需要在模型结构层面做适配比如把 SiLU 激活函数替换为 ReLU 可能让精度下降 0.5 个点。6.3 实测效果与性能数据我把完整方案在市区一段 3 公里测试路线包含 8 个红绿灯路口上进行了录屏回放测试指标数值信号灯检测 mAP500.94夜间场景 mAP500.87灯色分类准确率97.3%通行规则判定准确率95.8%单帧推理耗时1660 Ti, FP1618ms状态稳定切换延迟约 3 帧100ms误判主要出现在“黄灯→红灯”切换瞬间和“左转箭头灯熄灭但圆盘绿灯亮起”的组合场景前者是状态机的时间差导致后者是几何匹配需进一步优化。7. “高分项目”经验沉淀文档组织、答辩汇报与避坑指南7.1 项目文档怎么组织才像“高分项目”项目资料里我放了完整的项目文档模板以下几个模块是评委最容易关注的点问题定义为什么要做这个任务现有方案存在什么问题技术选型对比对比 YOLOv8 / YOLOv5 / Faster R-CNN / SSD 的性能和指标附上你自己的实测对比表比任何空讲都更有说服力。数据集构成与标注规范尽量量化说明各类别样本数、场景分布、标注标准的示意图。算法创新点如果你只是“用 YOLOv8 训了一个模型”那不够出彩。但如果你在 P2 层、数据增强策略、状态机后处理上做了优化每一点都是加分项。实验记录训练曲线、测试指标、消融实验比如“去掉 P2 层后 mAP 下降多少”“关闭 Mosaic 后 mAP 提升多少”。消融实验是高分项目的核心分水岭有条件和算力一定要做。7.2 答辩汇报最容易暴露的问题往年见过太多人栽在三个问题上第一说不清“信号灯检测”和“通行规则判定”的区别。上来就讲模型结构多先进结果评委一问“红灯亮时你直行车道能不能走”就卡壳了。正确的思路是先讲清楚框架分层再逐层展开。第二没有评估失败案例。任何真实项目都有边界坦白讲“在夜间强光晕、大逆光场景下系统仍存在漏检风险”远比吹嘘“准确率 100%”更可信也会显得你对问题有完整认知。第三演示视频没录好。这个项目本质是视觉项目如果答辩现场网络不好或者摄像头环境不对模型表现会大打折扣。我的建议是提前录制一段 3~5 分钟的完整演示视频分辨率 1080P画面稳定包含白天、夜间、雨天等场景。7.3 这个项目的后续扩展方向到这里整套方案的核心链路基本清楚。如果你还有余力有几个方向可以考虑把规则判定从“当前车道”扩展到“全路口多车道”结合多目标跟踪同时判断多个车道的通行权限。引入 V2X 概念通过路侧单元下发信号灯配时方案让车端模型和路侧信息做交叉验证提升安全性。尝试轻量化改进用 YOLOv8n 配合 INT8 量化配合知识蒸馏在极低算力设备上跑出可用精度。我在实际测试中体会最深的一件事是目标检测模型本身的精度只决定系统的上限而规则层、时序层和部署层的设计才真正决定这个项目能不能从“实验室 demo”走到真实路况。把这几个层面打通比单独刷高一个 mAP 指标有价值得多。本文还有配套的精品资源点击获取
返回列表