1. 项目概述:当YOLO遇见红绿灯
红绿灯识别是自动驾驶和辅助驾驶系统的核心功能之一,也是计算机视觉领域极具挑战性的任务。传统方法依赖颜色空间转换和模板匹配,但在复杂光照、遮挡情况下表现欠佳。我们采用YOLOv5构建的这套系统,在自制数据集上达到98.3%的检测准确率,且能在树莓派等边缘设备实现实时推理(15FPS)。系统包含完整的数据采集标注工具链、模型训练优化方案和基于PyQt的可视化界面,特别适合交通监控设备升级和车载系统二次开发。
2. 核心需求解析
2.1 交通场景的特殊挑战
城市道路中的信号灯识别面临三大难题:① 强光/逆光导致颜色失真 ② 小目标检测(远距离信号灯仅占图像0.1%像素) ③ 多状态分类(红/黄/绿灯及箭头方向)。我们在深圳南山区采集的实测数据显示,正午阳光直射时,传统HSV色彩空间方法的误检率高达42%。
2.2 技术选型依据
相比Faster R-CNN等两阶段检测器,YOLO的单阶段特性更适合实时系统。具体选择YOLOv5而非更新的v7/v8版本,主要考虑:① 社区支持完善 ② TensorRT加速方案成熟 ③ 模型尺寸可压缩至1.8MB(tiny版本)。测试表明,在GTX 1060显卡上,YOLOv5s的推理速度比v7快23%,而精度损失仅1.7%。
3. 数据集构建方法论
3.1 数据采集规范
我们使用海康威视DS-2CD3系列摄像头,以1080P分辨率采集不同时段(清晨/正午/黄昏/夜间)的交通路口视频。关键配置参数:
- 快门速度:1/500s(避免运动模糊)
- 白平衡:手动锁定5500K
- 曝光补偿:+0.7EV(保留暗部细节)
3.2 智能标注方案
采用LabelImg+CVAT组合工具链:
# 安装标注工具 pip install labelImg git clone https://github.com/opencv/cvat cd cvat && docker-compose up -d标注时特别注意:
- 包含灯罩整体作为检测框(不单截取发光区域)
- 对闪烁中的黄灯需标记为单独类别
- 为每个灯体添加方向属性(直行/左转/右转)
3.3 数据增强策略
通过albumentations库实现动态增强:
transform = A.Compose([ A.RandomSunFlare(flare_roi=(0,0,1,0.5), angle_lower=0.5), # 模拟眩光 A.RandomShadow(shadow_roi=(0,0.5,1,1)), # 道路阴影 A.ChannelShuffle(p=0.3), # 应对白平衡异常 A.RandomRain(drop_length=20, p=0.2) # 雨天场景 ])最终构建的数据集包含:
- 训练集:12,843张(8个城市)
- 验证集:1,426张
- 测试集:2,157张
4. 模型训练优化实战
4.1 骨干网络改造
原始YOLOv5的Focus模块在嵌入式设备上效率较低,我们替换为更轻量的Stem块:
class StemBlock(nn.Module): def __init__(self, c1, c2): super().__init__() self.conv1 = Conv(c1, c2//2, 3, 2) self.conv2 = Conv(c2//2, c2, 3, 1) def forward(self, x): return self.conv2(self.conv1(x))修改后模型参数量减少18%,推理速度提升15%。
4.2 损失函数优化
针对小目标检测,改进CIoU损失:
def compute_loss(pred, target): # 增加小目标权重 box_loss = 1.0 - (1.0 + 4.0*target[...,2]*target[...,3]) * CIoU(pred, target) cls_loss = FocalLoss(pred_cls, target_cls) return box_loss + cls_loss4.3 训练参数配置
关键超参数设置:
lr0: 0.01 # 初始学习率 lrf: 0.2 # 最终学习率 warmup_epochs: 3 batch_size: 32 fl_gamma: 1.5 # 聚焦困难样本 hsv_h: 0.015 # 色相增强 hsv_s: 0.7 # 饱和度增强使用余弦退火调度器,在Tesla T4上训练300epoch约需6小时。
5. 部署与界面开发
5.1 模型压缩方案
通过TensorRT加速实现边缘部署:
# 转换ONNX模型 python export.py --weights yolov5s.pt --include onnx # 生成TensorRT引擎 trtexec --onnx=yolov5s.onnx --fp16 --workspace=2048在Jetson Nano上测试,FP16精度下速度从9FPS提升至22FPS。
5.2 PyQt界面设计
GUI功能模块包括:
- 视频流显示区(QPixmap)
- 检测结果叠加层(QGraphicsItem)
- 日志记录系统(QTextEdit) 关键交互代码:
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.model = torch.hub.load('ultralytics/yolov5', 'custom', path='best.pt') def process_frame(self, img): results = self.model(img) self.display_results(results)6. 实测性能与调优
6.1 精度指标对比
在自建测试集上的表现:
| 模型 | mAP@0.5 | 红灯召回率 | 黄灯准确率 | 推理速度 |
|---|---|---|---|---|
| YOLOv5s | 0.923 | 0.951 | 0.887 | 45FPS |
| YOLOv5m | 0.938 | 0.962 | 0.901 | 32FPS |
| 改进YOLOv5s | 0.941 | 0.968 | 0.915 | 52FPS |
6.2 典型问题解决
- 误检问题:通过添加负样本(类似信号灯的圆形物体)训练,误检率从8.3%降至2.1%
- 漏检问题:在FPN层增加P2特征图(160x160分辨率),小目标召回率提升19%
- 分类混淆:引入方向敏感卷积核,箭头方向识别准确率从82%提高到94%
7. 工程实践建议
数据采集避坑:
- 避免在雾天拍摄(能见度<500米时图像质量骤降)
- 每个路口至少采集3个不同角度的视频
- 使用偏振镜消除玻璃反光
标注质量控制:
# 验证标注一致性 def check_annotations(): for img in dataset: h, w = img.shape[:2] for box in annotations: assert 0 <= box.xmin < box.xmax <= w assert 0 <= box.ymin < box.ymax <= h部署优化技巧:
- 对固定摄像头场景,可限定检测ROI区域
- 开启CUDA Graph优化可减少5-8ms延迟
- 使用多线程流水线处理(采集+推理+显示并行)
这套系统在实际交通监控项目中表现出色,特别是在暴雨天气下的鲁棒性远超商用方案。有个值得注意的细节:夜间模式建议关闭HSV增强,否则车灯眩光会导致大量误检。我们在东莞某智能路口部署的版本,连续运行6个月未出现故障,平均检测延迟控制在65ms以内。