基于YOLOv5与HSV的轻量级红绿灯识别系统开发

发布时间:2026/7/24 16:00:30

基于YOLOv5与HSV的轻量级红绿灯识别系统开发 1. 项目背景与核心价值红绿灯识别是智能交通系统中最基础也最关键的感知环节。去年我在参与一个城市智慧交通项目时发现现有信号灯检测方案存在两个痛点一是传统图像处理方法在复杂光照条件下误检率高二是商业算法库价格昂贵且灵活性差。于是用Python开发了这套轻量级识别系统在树莓派4B上实测准确率达到94%成本不到商业方案的十分之一。这个系统特别适合三类场景自动驾驶原型车的环境感知模块交叉路口违章抓拍系统的辅助验证智慧交通教学实验平台开发核心创新点在于将YOLOv5的检测速度与HSV色彩空间分析结合既保证了实时性30FPS1080p又能有效应对逆光、阴雨等复杂条件。下面分享具体实现方案和踩坑经验。2. 技术方案设计2.1 整体架构设计系统采用经典的检测-识别-跟踪三级流水线摄像头输入 → 信号灯检测 → 状态识别 → 输出结果 ↑____________跟踪反馈_________↑关键设计考量检测模块选用YOLOv5s而非更大的模型因为在640x640输入下已有足够精度mAP0.50.89且推理速度比v5x快3倍识别模块采用HSV空间分析替代RGB因为色度Hue通道对光照变化更鲁棒可设置固定阈值范围红0-10/160-180绿35-90跟踪模块用OpenCV的KCF跟踪器减少每帧全图检测的计算量2.2 硬件选型建议经过实测对比推荐以下配置组合设备类型推荐型号性能表现适用场景开发板树莓派4B15FPS720p教学/原型开发嵌入式Jetson Nano28FPS1080p边缘部署工控机NUC11i560FPS4K交通监控特别注意使用树莓派时建议搭配官方摄像头模块而非USB摄像头可避免MJPEG解码带来的延迟3. 核心代码实现3.1 YOLOv5检测适配关键改造点是在detect.py中增加信号灯专属后处理def post_process(detections): # 只保留交通灯类别的检测结果COCO数据集中第9类 traffic_light_mask (detections[:, -1] 9) valid_detections detections[traffic_light_mask] # 根据置信度过滤阈值设为0.6 conf_mask (valid_detections[:, 4] 0.6) final_detections valid_detections[conf_mask] # 按置信度降序排列 return final_detections[final_detections[:, 4].argsort()[::-1]]3.2 状态识别算法核心是提取ROI区域后的HSV分析def recognize_light_state(img_roi): hsv cv2.cvtColor(img_roi, cv2.COLOR_BGR2HSV) # 定义红绿灯的HSV范围 red_lower1 np.array([0, 120, 70]) red_upper1 np.array([10, 255, 255]) red_lower2 np.array([160, 120, 70]) red_upper2 np.array([180, 255, 255]) green_lower np.array([35, 50, 50]) green_upper np.array([90, 255, 255]) # 创建掩膜 red_mask1 cv2.inRange(hsv, red_lower1, red_upper1) red_mask2 cv2.inRange(hsv, red_lower2, red_upper2) red_mask cv2.bitwise_or(red_mask1, red_mask2) green_mask cv2.inRange(hsv, green_lower, green_upper) # 计算像素占比 red_ratio np.count_nonzero(red_mask) / (img_roi.size / 3) green_ratio np.count_nonzero(green_mask) / (img_roi.size / 3) # 状态判定阈值设为20% if red_ratio 0.2: return RED elif green_ratio 0.2: return GREEN else: return UNKNOWN4. 性能优化技巧4.1 加速推理的实测对比在Jetson Nano上测试不同优化方案优化方法推理时间(ms)内存占用(MB)原始模型581200FP16量化42980TensorRT28650ONNX Runtime35720建议优先尝试TensorRT虽然转换复杂但收益最大。具体步骤导出ONNX格式python export.py --weights yolov5s.pt --include onnx用trtexec工具转换trtexec --onnxyolov5s.onnx --fp16 --saveEngineyolov5s.engine4.2 多目标跟踪优化当画面中出现多个信号灯时建议采用以下策略为每个检测到的灯分配唯一ID使用匈牙利算法解决帧间匹配问题对持续跟踪的目标降低检测频率如每5帧做一次全检测关键代码片段trackers [] max_age 5 # 最大丢失帧数 for det in detections: x,y,w,h det[:4] tracker cv2.TrackerKCF_create() tracker.init(frame, (x,y,w,h)) trackers.append({ tracker: tracker, id: len(trackers), age: 0, state: recognize_light_state(frame[y:yh, x:xw]) })5. 典型问题解决方案5.1 误识别场景处理常见误识别场景及应对措施问题现象可能原因解决方案红灯识别为绿灯刹车灯干扰增加长宽比过滤信号灯通常宽高比1.5夜间误识别环境光干扰启用直方图均衡化CLAHE远处目标漏检小目标问题修改YOLOv5的anchor尺寸5.2 雨天性能下降对策实测发现雨天准确率会下降15-20%推荐三个改进方向图像预处理增加同态滤波消除水雾影响def homomorphic_filter(img): gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) rows, cols gray.shape img_log np.log1p(np.float32(gray)) # 傅里叶变换 M, N cv2.getOptimalDFTSize(rows), cv2.getOptimalDFTSize(cols) dft np.fft.fft2(img_log, s(M,N)) # 构造高斯高通滤波器 sigma 0.5 H 1 - np.exp(-((np.arange(M) - M//2)**2 (np.arange(N) - N//2)**2) / (2*sigma**2)) # 滤波反变换 filtered dft * H img_filtered np.fft.ifft2(filtered) return np.uint8(np.exp(np.real(img_filtered[:rows,:cols])) - 1)数据增强训练时添加雨雾合成数据多帧验证要求连续3帧识别结果一致才输出6. 部署实践建议6.1 树莓派部署要点系统配置# 启用摄像头接口 sudo raspi-config # Interface Options → Camera # 安装必要库 sudo apt install libatlas-base-dev libopenblas-dev pip install torch1.8.0 torchvision0.9.0 -f https://download.pytorch.org/whl/raspberrypi/torch_stable.html开机自启动配置# /etc/rc.local 中添加 su pi -c python3 /home/pi/traffic_light/main.py --source 0 --imgsz 640 6.2 工业环境注意事项防抖措施安装时使用减震支架避免风力导致画面模糊夜间补光建议使用850nm红外补光灯不影响信号灯颜色识别散热方案连续工作时Jetson Nano需加装散热风扇否则会因降频导致帧率减半这套系统在深圳某十字路口的实测数据显示早高峰时段的识别准确率保持在91%以上平均延迟仅35ms。最让我意外的是对箭头型信号灯的识别效果比预期更好这得益于YOLOv5对不规则目标的检测能力。如果要做进一步优化我会考虑加入时间序列分析来预测信号切换时机。

相关新闻