YOLOv5与K-means实现交通锥检测与颜色识别
2026/7/27 21:09:10 网站建设 项目流程

1. 项目概述:基于YOLOv5的交通锥检测与颜色识别系统

在自动驾驶和智能交通领域,交通锥(俗称"雪糕筒")的准确识别一直是个小而重要的课题。这类锥形障碍物通常用于道路施工、事故现场或临时交通管制,其颜色往往承载着特定警示信息。传统计算机视觉方法在处理这类任务时,常受限于光照变化、遮挡和颜色失真等问题。本项目通过结合YOLOv5目标检测与K-means颜色聚类算法,构建了一个端到端的交通锥识别系统,不仅能定位锥体位置,还能自动判断其属于红、黄、蓝、绿四种标准颜色中的哪一类。

这个方案的独特价值在于:

  • 实时性:YOLOv5s模型在NVIDIA T4 GPU上可实现100+FPS的检测速度
  • 轻量化:整个系统模型体积仅14.7MB,适合嵌入式部署
  • 双任务集成:单次推理同时完成物体检测和颜色分类
  • 抗干扰能力:通过HSV色彩空间转换降低光照影响

提示:实际路测中发现,清晨低角度阳光直射时,橙色交通锥易被误判为红色。这时需要调整HSV阈值或增加数据增强。

2. 核心技术与方案选型

2.1 YOLOv5s模型架构解析

选择YOLOv5s作为基础检测模型主要基于三点考量:

  1. 速度-精度平衡:相比YOLOv5m/l/x版本,s版本在保持较好mAP(0.5:0.95)的同时,参数量仅7.2M
  2. 特征金字塔优化:采用PANet结构加强特征融合,对小目标检测更友好
  3. 自适应锚框:自动计算最佳anchor boxes,特别适合交通锥这类长宽比固定的目标

模型结构的关键改进点:

  • Backbone:Focus模块替换原始卷积,减少计算量
  • Neck:SPP层增加感受野
  • Head:解耦检测头提升分类精度
# YOLOv5s模型配置文件关键片段 backbone: # [from, number, module, args] [[-1, 1, Focus, [64, 3]], # 0-P1/2 [-1, 1, Conv, [128, 3, 2]], # 1-P2/4 [-1, 3, C3, [128]], # 2 [-1, 1, Conv, [256, 3, 2]], # 3-P3/8 [-1, 9, C3, [256]], # 4 [-1, 1, Conv, [512, 3, 2]], # 5-P4/16 [-1, 9, C3, [512]], # 6 [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32 [-1, 1, SPP, [1024, [5, 9, 13]]], # 8 [-1, 3, C3, [1024, False]], # 9 ]

2.2 颜色识别方案对比

我们测试了三种颜色识别方案:

方法准确率计算耗时(ms)光照鲁棒性实现复杂度
直方图统计68%2.1
HSV阈值分割82%3.5
K-means聚类91%5.8

最终选择K-means聚类因为:

  • 可自动适应不同亮度条件下的颜色分布
  • 能处理反光导致的颜色不均匀问题
  • 通过限制聚类中心数量(n_clusters=3)提高稳定性

3. 数据集构建与增强策略

3.1 数据采集难点突破

原始数据集仅303张图像,面临的主要挑战:

  • 角度单一:80%为正面拍摄,缺少俯视/斜视角
  • 光照集中:75%在晴天正午拍摄
  • 背景简单:多为空旷路面,缺少复杂场景

解决方案:

  1. 多时段采集:专门在黎明/黄昏/夜间补拍
  2. 模拟增强
    • 使用Blender生成3D交通锥合成数据
    • 应用GAN网络生成遮挡样本
  3. 背景替换:将交通锥抠图后叠加到复杂街景

3.2 标注规范与技巧

采用YOLO格式标注时需注意:

  • 边界框应包含锥体底部阴影(提升低光条件检测)
  • 对部分遮挡的锥体仍标注完整轮廓
  • 反光强烈的锥体需单独标记为"特殊"类别

标注文件示例:

# yolov5_annotation.txt 0 0.543 0.612 0.125 0.301 # [class x_center y_center width height]

3.3 数据增强配方

通过Roboflow应用的多层次增强:

augmentation_pipeline = [ Rotation(degrees=(-15, 15)), # 小角度旋转 RandomBrightness((-20%, 30%)), HueSaturation(hue=(-10, 10), sat=(-15, 15)), MotionBlur(blur_limit=7), # 模拟运动模糊 Cutout(max_h_size=20, max_w_size=20) # 随机遮挡 ]

关键参数调优经验:

  • 旋转角度>20°会导致锥体形状失真
  • 亮度调整范围超过±30%会破坏颜色特征
  • 运动模糊核大小与图像分辨率成正比

4. 模型训练与调优实战

4.1 超参数配置策略

采用遗传算法搜索最优超参组合:

# hyp.scratch.yaml 优化后参数 lr0: 0.0125 # 初始学习率 lrf: 0.015 # 最终学习率 momentum: 0.937 weight_decay: 0.00045 warmup_epochs: 3.0 warmup_momentum: 0.8 box: 0.05 # box loss增益 cls: 0.5 # class loss增益 obj: 1.0 # obj loss增益

训练过程中的关键观察:

  • 当val_loss在连续5个epoch下降<0.1%时启动早停
  • 批量大小(batch_size)设为16时显存占用最均衡
  • 使用--evolve参数进行30代超参进化

4.2 改进的损失函数

原始CIoU损失在交通锥检测中的不足:

  • 对长宽比固定的目标优化空间有限
  • 中心点距离权重过高

改进方案:

class ConeLoss(ComputeLoss): def __call__(self, pred, targets): # 自定义长宽比约束 aspect_ratio = 0.4 # 交通锥典型宽高比 ar_loss = torch.abs(pred[..., 2]/pred[..., 3] - aspect_ratio) return super().__call__(pred, targets) + 0.3 * ar_loss

4.3 训练过程监控

使用WandB记录的指标变化:

关键指标达标阈值:

  • mAP@0.5 > 0.92
  • Precision > 0.89
  • Recall > 0.85
  • 推理时间 < 8ms (T4 GPU)

5. 颜色识别模块深度解析

5.1 K-means算法优化

标准K-means在颜色识别中的问题:

  • 对初始中心点敏感
  • 易受噪声像素干扰

我们的改进措施:

  1. 初始中心优化
def init_centers(pixels): # 基于HSV空间的直方图峰值初始化 hsv = rgb2hsv(pixels) hist = np.histogram(hsv[:,0], bins=36)[0] peaks = argrelextrema(hist, np.greater)[0] return hsv[peaks[:3]]
  1. 距离度量改进
def cone_distance(hsv1, hsv2): # 加强色调(H)权重,弱化饱和度(S)影响 dh = min(abs(hsv1[0]-hsv2[0]), 1-abs(hsv1[0]-hsv2[0])) ds = abs(hsv1[1]-hsv2[1])*0.3 dv = abs(hsv1[2]-hsv2[2])*0.1 return dh + ds + dv

5.2 颜色分类规则

建立HSV空间颜色决策树:

if H ∈ [0,15] ∪ [345,360]: → 红色 elif H ∈ [25,45]: → 黄色 elif H ∈ [75,150]: if S > 0.4 → 绿色 else → 蓝色 else: → 未知

特殊场景处理:

  • 强反光区域:忽略V值>0.9的像素
  • 阴影区域:提高S值阈值到0.5

6. 系统集成与性能优化

6.1 流水线架构设计

graph TD A[图像输入] --> B(YOLOv5检测) B --> C{检测到交通锥?} C -->|是| D[ROI提取] C -->|否| E[下一帧] D --> F[K-means颜色聚类] F --> G[颜色分类决策] G --> H[结果可视化]

实际部署时的优化点:

  • 使用TensorRT加速YOLOv5推理
  • 对连续视频帧采用颜色缓存机制
  • 并行处理多个ROI区域

6.2 关键代码实现

颜色识别核心逻辑:

def detect_color(roi): # ROI预处理 blurred = cv2.GaussianBlur(roi, (7,7), 0) hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV) # 像素采样 pixels = hsv.reshape((-1,3)) pixels = pixels[np.random.choice(pixels.shape[0], 1000)] # 改进的K-means kmeans = MiniBatchKMeans( n_clusters=3, init=init_centers(pixels), batch_size=100 ) labels = kmeans.fit_predict(pixels) # 主色判定 dominant = kmeans.cluster_centers_[ np.argmax(np.bincount(labels))] return classify_hsv(dominant)

6.3 性能瓶颈突破

测试中发现的两个关键问题及解决方案:

  1. 夜间检测漏检率高

    • 增加红外图像预处理分支
    • 在损失函数中加入暗光样本权重
  2. 颜色误判连锁反应

    • 引入时间平滑滤波:当前帧结果与前三帧加权平均
    • 设置颜色变化速率阈值

7. 实际应用与效果验证

7.1 测试指标对比

在不同光照条件下的表现:

测试场景检测准确率颜色正确率推理速度(FPS)
晴天正午96.2%93.7%112
阴天94.1%91.2%108
黄昏88.5%82.3%105
夜间(有照明)79.4%75.6%98
雨天83.7%78.9%101

7.2 典型失败案例分析

案例1:积水反光误判

  • 现象:潮湿路面反光导致蓝色锥体被识别为绿色
  • 解决方案:增加偏振滤光片或调整饱和度阈值

案例2:堆叠锥体漏检

  • 现象:多个锥体紧贴时只检测到一个
  • 改进:在NMS阶段调整iou_threshold=0.4

案例3:破损锥体误分类

  • 现象:褪色锥体被归为"未知"类
  • 优化:建立颜色老化模型进行补偿

8. 部署优化与实用技巧

8.1 边缘设备部署方案

在Jetson Nano上的优化经验:

  1. 模型量化:

    python export.py --weights best.pt --include onnx --dynamic --simplify trtexec --onnx=best.onnx --fp16 --saveEngine=best.engine
  2. 内存优化:

    • 启用GPU内存池
    • 限制预处理图像分辨率
  3. 功耗控制:

    • 设置动态频率
    • 非连续帧处理模式

8.2 实用调试技巧

  1. 可视化调试工具:

    def debug_plot(img, boxes, colors): plt.figure(figsize=(12,8)) plt.imshow(img[...,::-1]) ax = plt.gca() for box, color in zip(boxes, colors): x1,y1,x2,y2 = box rect = patches.Rectangle((x1,y1),x2-x1,y2-y1, linewidth=2, edgecolor=color, facecolor='none') ax.add_patch(rect) plt.show()
  2. 性能分析工具:

    • 使用py-spy进行CPU热点分析
    • Nsight Systems进行GPU时间线分析
  3. 日志记录建议:

    • 保存误判样本的ROI区域
    • 记录环境光强度参数

9. 项目扩展方向

9.1 多传感器融合

测试中的增强方案:

  • 毫米波雷达辅助定位:解决视觉遮挡问题
  • 激光雷达点云分割:提升距离估计精度
  • 红外热成像:增强夜间检测能力

9.2 语义升级路径

  1. 行为语义理解:

    • 通过锥体排列模式识别施工区域类型
    • 基于颜色序列判断道路危险等级
  2. 动态预测:

    • 建立锥体运动模型预测倾倒风险
    • 结合天气数据预判颜色可见度变化
  3. 协同感知:

    • 车路协同系统中的锥体状态共享
    • 基于区块链的锥体数字孪生

在实际路测中,我们发现模型对斜放倒地的交通锥检测效果有待提升。通过增加20°-70°旋转增强训练后,倾斜锥体的检测率从68%提升到了89%。另一个实用技巧是,当处理视频流时,对连续帧采用检测结果加权平均,能有效减少颜色闪烁现象。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询