1. 项目背景与核心价值
红绿灯识别是智能交通系统和自动驾驶领域的基础能力之一。传统方案依赖专用硬件和固定摄像头,而基于计算机视觉的软件解决方案具有部署灵活、成本低廉的优势。这个Python项目实现了从普通摄像头视频流中实时检测交通信号灯状态的功能,核心解决了三个问题:
- 复杂环境下的信号灯定位(雨天/夜间/遮挡场景)
- 多类型信号灯状态识别(箭头灯、倒计时灯、行人灯等)
- 实时性保障(30fps视频流处理)
我在实际道路测试中发现,商用级识别系统在树影遮挡情况下的误判率高达42%,而本项目通过改进的YOLOv5模型+HSV色彩空间分析的双重校验机制,将误判率控制在8%以下。
2. 技术架构设计
2.1 整体处理流程
graph TD A[视频输入] --> B[帧提取] B --> C[目标检测] C --> D[ROI提取] D --> E[颜色分析] E --> F[状态判定] F --> G[输出结果]2.2 核心组件选型
检测模型:
- 基准模型:YOLOv5s (3.2MB)
- 改进方案:添加SE注意力模块的YOLOv5m (14.4MB)
- 测试数据对比:
模型 mAP@0.5 推理速度(FPS) 显存占用 v5s 0.78 62 1.2GB v5m-se 0.89 38 2.4GB
颜色分析:
- 采用HSV空间而非RGB:
def rgb_to_hsv(rgb_img): hsv_img = cv2.cvtColor(rgb_img, cv2.COLOR_RGB2HSV) # 红色需要特殊处理(Hue通道环绕特性) lower_red1 = np.array([0, 70, 50]) upper_red1 = np.array([10, 255, 255]) lower_red2 = np.array([170, 70, 50]) upper_red2 = np.array([180, 255, 255]) return hsv_img状态机设计:
- 消除闪烁造成的误判:
class TrafficLightFSM: def __init__(self): self.state = "UNKNOWN" self.confidence = 0 def update(self, new_state): if new_state == self.state: self.confidence = min(10, self.confidence + 1) else: self.confidence = max(0, self.confidence - 2) if self.confidence >= 5: return self.state return "TRANSITION"
3. 关键实现细节
3.1 数据准备技巧
自制数据集构建:
- 使用LabelImg标注工具时,建议采用YOLO格式而非Pascal VOC
- 数据增强策略:
transform = A.Compose([ A.RandomRain(drop_length=5, blur_value=3, p=0.3), A.RandomShadow(num_shadows_low=1, num_shadows_high=2, p=0.5), A.RandomSunFlare(p=0.2), A.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.1, p=0.8) ])
类别不平衡处理:
- 采用Focal Loss替代交叉熵:
class FocalLoss(nn.Module): def __init__(self, alpha=0.25, gamma=2): super().__init__() self.alpha = alpha self.gamma = gamma def forward(self, inputs, targets): BCE_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduction='none') pt = torch.exp(-BCE_loss) loss = self.alpha * (1-pt)**self.gamma * BCE_loss return loss.mean()
3.2 模型优化技巧
剪枝量化方案:
python export.py --weights best.pt --include onnx --simplify --dynamic python -m onnxruntime.tools.convert_onnx_models_to_ort best.onnxINT8量化效果对比:
精度 模型大小 推理速度 准确率下降 FP32 14.4MB 38FPS 基准 INT8 3.6MB 72FPS <2%
4. 部署实战
4.1 边缘设备部署
Jetson Nano优化:
import tensorrt as trt logger = trt.Logger(trt.Logger.WARNING) with trt.Builder(logger) as builder: network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, logger) with open("best.onnx", "rb") as model: parser.parse(model.read()) config = builder.create_builder_config() config.set_flag(trt.BuilderFlag.FP16) engine = builder.build_engine(network, config)性能对比:
设备 帧率 功耗 温度 Jetson Nano 24FPS 10W 68℃ Raspberry Pi4 8FPS 6W 52℃ Intel NUC 56FPS 28W 72℃
4.2 实际测试问题
典型误判场景:
- 夕阳红色光干扰(解决方案:增加亮度阈值判断)
- LED广告牌干扰(解决方案:形状轮廓分析)
- 部分遮挡情况(解决方案:时序预测补偿)
精度优化记录:
优化措施 准确率提升 耗时增加 基础YOLOv5 78.2% - +HSV校验 85.7% +8ms +时序滤波 91.3% +3ms +多角度集成 93.5% +15ms
5. 工程化建议
日志监控系统:
class TrafficLightLogger: def __init__(self): self.buffer = deque(maxlen=100) def log(self, frame, bbox, state, confidence): entry = { "timestamp": time.time(), "frame_hash": hashlib.md5(frame.tobytes()).hexdigest(), "bbox": bbox, "state": state, "confidence": confidence } self.buffer.append(entry)异常处理机制:
def safe_detect(frame): try: if frame.mean() < 10: raise LowIlluminationError return model(frame) except Exception as e: logging.error(f"Detection failed: {str(e)}") return backup_optical_flow_estimate()
关键提示:实际部署时要特别注意不同地区信号灯的标准差异,例如中国横向排列信号灯与欧美纵向排列的识别策略需要针对性调整。建议建立地域配置文件机制:
# config/region_cn.yaml light_layout: horizontal red_position: left timeout: 30
这个项目最让我意外的是颜色空间转换的开销占比——在Jetson Nano上,cv2.cvtColor操作竟然占用了23%的处理时间。后来通过将BGR->HSV转换合并到图像预处理管线中,整体速度提升了18%。这提醒我们:在边缘计算场景下,连OpenCV这种基础操作都需要精心优化。