EXP-02 · 8 学时(2 理论 + 6 实践)

交通标志与红绿灯识别

把 HP60C 拍到的画面变成两路标准话题:HSV 颜色分割判定红绿灯红/黄/绿三态发 /traffic/light,NPU 上的 YOLO 检测直行/转向/停车/注意行人四类标志发 /traffic/sign——验收标准:三态灯识别准确率 ≥95%、四类标志 mAP 达标且置信度可调,光照变化后 5 分钟内完成重标定。

理论2+实践6OpenCV HSVNPU / YOLOv8 RKNN/traffic/light · /traffic/sign光照鲁棒性

01本节目标

  • 启动 HP60C 相机驱动,核对 /ascamera_hp60c/** 话题树,明确 0.5m 近盲区对识别距离的约束(识别距离应保持 0.3~0.8m)。
  • 讲清 HSV 颜色分割为什么能判灯态:H 通道与色调的对应关系、阈值窗口、形态学去噪三件套。
  • 完成红绿灯三态(红/黄/绿)识别节点,输出 /traffic/light 话题(data: R/Y/G)。
  • 完成四类交通标志(直行/转向/停车/注意行人)NPU 检测,输出 /traffic/sign 话题(类别 + 置信度)。
  • 会做阈值与置信度调优:换光照/夜晚灯光下重新标定 HSV 区间,理解 [email protected] 与置信度阈值的取舍。
  • 牢记:识别是 EXP-03 控制的输入——话题断 1 帧,路口状态机就少一分把握。
素材说明:本实验无实拍素材,示意图与交互动画为准;红绿灯与标志牌两幅参照图抓自 Hiwonder 官方产品页(公开图),仅作规格参考,以现场沙盘实际元素为准。

02核心原理:光如何变成话题——HSV 判灯与 NPU 检测双通道

把识别想成交通协管员:他盯灯用"颜色直觉"(这盏灯发红光——色相对了就是红灯,亮不亮只是阈值问题),认标志用"图形记忆"(圆形蓝底带箭头=直行)。第一条通道 HSV 颜色分割正对应"直觉":RGB 三通道把亮度和颜色搅在一起,转到 HSV 后 H(色调)单独承载"是什么颜色"——红灯 H≈0-10 或 170-180(红环抱 0°),绿灯 H≈35-85,黄灯 H≈20-35,各留 ±10 窗口吸收 LED 色偏与白平衡漂移;S、V 通道卡"够不够饱和、够不够亮"排除反光与暗影,再用开运算去掉标线反光的碎斑,取连通域最大者判定灯态。

第二条通道 YOLO + NPU 对应"图形记忆":四类标志长得像(都是牌面),靠颜色会翻车——直行/转向是蓝底白图案,停车是红圈白底,注意行人是黄三角。yolov8n 在 PC 上训好 → 转 RKNN INT8 → 塞进 C1 的 6 TOPS NPU,前向推理吃掉大头 CPU;输出框经 NMS 去重后按置信度过滤,封装成 std_msgs/String JSON 发 /traffic/sign。两路话题合流,EXP-03 的状态机才有"灯态 + 交规牌"两本经。

灯态判定状态机(HSV 输出驱动,周期 48s 同 EXP-01 模拟器) 红灯 R HSV: H 0-10/170-180 黄灯 Y H 20-35 · 过渡 5s 绿灯 G H 35-85 · 25s 黄灯 5s 绿灯 25s 红灯 3s(含全红清空) 判定输出 /traffic/light: R|Y|G —— 稳定 3 帧一致才发布,防闪烁
图 2-1|自制示意图:红绿灯状态机——HSV 分割输出经三帧稳定滤波后驱动 R→Y→G 周期迁移,与 EXP-01 配时模拟器共用 48s 周期参数。
话题类型频率消费方
/traffic/lightstd_msgs/String:R / Y / G10 Hz(三帧稳定后发布)EXP-03 路口状态机、EXP-04 路测评分
/traffic/signstd_msgs/String:{cls, conf, dist}15 Hz(NPU 推理节流)EXP-03 转向决策、EXP-04 按标志改道
/ascamera_hp60c/color_imagesensor_msgs/Image30 fps识别节点唯一输入源

03硬件与场景

HP60C 深度相机
话题 /ascamera_hp60c/**;0.5m 近盲区——识别机位保持 0.3~0.8m,贴太近画面丢失;曝光设为自动+锁定参考帧。
6 TOPS NPU
yolov8n→RKNN INT8 部署,推理 <15ms/帧;NPU 忙时先降分辨率 640→416,不降置信度。
红绿灯模型
立式三色灯(参照规格高约 24cm),LED 直射易过曝——HSV 的 V 上限留 255,S 下限提到 60 滤白反光。
四类交通标志
直行×2、转向、停车、注意行人(参照规格牌面 8×8cm);训练集覆盖 0.3/0.5/0.8m 三档距离与 30° 侧视角。
先决检查标准不达标后果
相机画面ros2 topic hz /ascamera_hp60c/color_image ≈30Hz识别节点空转,/traffic/* 无输出
模型文件traffic_sign.rknn 校验和与版本记录类别错位,四类混淆
光照基线开灯状态拍 10 帧存参考图换灯后无对照,误判"识别坏了"
NPU 占用rknpu2 服务在跑、无其他模型抢占推理排队、帧率掉到 5Hz
沙盘红绿灯模型参照图
图 2-2|红绿灯模型参照(网抓自 Hiwonder 官方产品页,非本教室实拍):立式三色灯,红/黄/绿三窗垂直排列——HSV 分割先框定灯窗 ROI 再在窗内判色,可显著降低误检。
交通标志牌参照图
图 2-3|交通标志牌参照(网抓自 Hiwonder 官方产品页,非本教室实拍):转向标志牌面约 8×8cm、杆高约 16cm——蓝底黄白箭头是转向类的主特征,检测框中心到杆底的投影距离可反推"远近"供改道决策用。

04操作步骤

S1起相机
hp60c.launch.py → 确认话题树与帧率
→
S2HSV 标定
截三态灯帧 → trackbar 拖阈值 → 存 hsv_config.yaml
→
S3灯态节点
分割+形态学+最大连通域 → 三帧稳定 → 发 /traffic/light
→
S4NPU 标志检测
yolov8n 数据增强 → RKNN INT8 → 部署 → 发 /traffic/sign
→
S5调优与鲁棒性
置信度滑杆、换光照重标定 → 20 轮三态+四类回归测试
  1. HSV 标定:分别在红/黄/绿亮灯时截帧,开 trackbar 拖 H/S/V 三组上下限,直到掩膜只剩灯窗、文字反光被 S≥60 滤掉;把均值写入 hsv_config.yaml,禁止把阈值硬编码进节点。
  2. 三帧稳定:连续 3 帧判定一致才发布,防 LED 频闪与压缩噪点造成 R/Y/G 抖动;发布后 ros2 topic echo /traffic/light 人工对表 10 轮。
  3. NPU 链路:PC 上用 1500+ 张四类增强数据(旋转/亮度/侧角)训 yolov8n → export ONNX → rknn-toolkit2 转 INT8(校准集 200 张)→ 拷贝到 C1 加载,rknpu2_server 占用确认。
  4. 性能核对:NPU 推理延迟打印 <15ms,端到端 /traffic/sign 频率 ≥15Hz;置信度阈值初始 0.55,误检多升 0.05,漏检多降 0.05——每次调整记录在调参表。
  5. 光照鲁棒:关顶灯/开台灯/夜晚三种光照各跑 20 轮回归,绿灯误判红灯 ≤1 次;换光照后 5 分钟内完成重标定是验收硬指标。
  6. 留痕:保存 hsv_config.yaml、rknn 版本、20 轮混淆矩阵截图,作为准确率 ≥95% 的证据。

05关键命令

相机与 YOLO 部署口径与《培训方案》xlsx 一致(ascamera hp60c.launch.py、python src/app.py、--model rknn)。

# ① 启动 HP60C 相机并核对话题树(EXP-01 用不到相机,本实验起全程在线)
ros2 launch ascamera hp60c.launch.py
ros2 topic list | grep ascamera_hp60c
ros2 topic hz /ascamera_hp60c/color_image        # ≈30Hz

# ② 截帧做 HSV 标定(三态灯各一张)+ 运行灯态识别节点
ros2 run image_tools cam2image --ros-args -p output_image:=/tmp/red.png
python3 src/light_node.py --config config/hsv_config.yaml
ros2 topic echo /traffic/light                   # 期望 R / Y / G 稳定输出

# ③ 手动发布一条灯态供 EXP-03 联调(无相机时的替身)
ros2 topic pub --once /traffic/light std_msgs/String "{data: 'R'}"

# ④ YOLO 训练→NPU 部署(PC 训练,C1 推理)
yolo train model=yolov8n.yaml data=traffic_sign.yaml epochs=120 imgsz=640
python3 src/export_rknn.py --model best.pt --quantize int8 --platform rk3588
python3 src/app.py --model models/traffic_sign.rknn --topic /ascamera_hp60c/color_image

# ⑤ 观察检测输出 / 端到端延迟
ros2 topic echo /traffic/sign                    # {cls, conf, dist}
ros2 topic hz /traffic/sign                      # ≥15Hz
验收标准(写入 s4 打卡):① 三态灯 20 轮 ×3 光照准确率 ≥95%;② 四类标志在 0.3/0.5/0.8m 三档距离均检出、置信度中位数 ≥0.6;③ 换光照 5 分钟内重标定完成并复测通过。易错点:识别距离小于 0.3m 进近盲区白屏、忘记三帧稳定导致灯态抖动、INT8 校准集没覆盖夜晚帧。
HSV 为什么不直接用 RGB
V 变化会同时拉动 R/G/B;H 对亮度不敏感,换灯、过曝时更稳。
置信度阈值的两难
0.55 是起点:升→漏 (注意行人)、降→幻觉 (转向误报);用 PR 曲线找拐点而非拍脑袋。
灯 vs 牌 谁先判
灯走 ROI 颜色(毫秒级),牌走 NPU(十毫秒级);路口先看灯,灯绿再消费标志改道。
/traffic/* 为何用 String
跨节点接口越简单越稳:JSON 字段 cls/conf/dist 够 EXP-03/04 用,避免自定义 msg 的编译耦合。

06原理动画:HSV 判灯链路与 NPU 检测管线

一帧画面 → 掩膜 → 最大连通域 → 灯态话题 原帧 ROI HSV 掩膜 形态学 + 连通域 开运算去碎斑 取面积最大者 /traffic/light R Y G 红 3s 黄 5s 绿 25s 黄点流=当前帧颜色样本;三帧一致才把 R/Y/G 发布出去,防频闪抖动
动画 2-1:原帧 ROI 中三窗只有一窗过阈值 → 掩膜亮斑 → 开运算滤碎斑 → 最大连通域定灯态 → 稳定三帧后发布 /traffic/light。
HP60C 帧640×640 letterbox yolov8n 骨干CSPDarknet 特征 NPU INT86 TOPS · <15ms NMSIoU 去重 sign话题 检测帧视窗(动态盒):置信度阈值 0.55,低于线的框直接丢弃 直行 0.87 转向 0.72 停车 0.41 弃 注意行人 0.79
动画 2-2:帧进 NPU 出框——0.87 的直行与 0.79 的注意行人稳过阈值,0.41 的停车框在线下被丢弃;这就是"置信度调优"实际在调的闸门。
观察灯走 HSV、牌走 YOLO,为什么不统一用 YOLO?——灯态是三分类颜色问题,HSV 毫秒级、零训练数据、可解释;牌是四类形状问题,颜色重叠严重才需要深度模型。能用简单规则解决的,不要喂数据——工程里这叫模型选型的最小充分原则。

07互动实验:四类标志识别小测

抽题识别:把"你看到的牌"翻译成 /traffic/sign 消息,对拍置信度
得分 0/0
点击「抽题」开始:识别正确类别并估计置信度 四类:直行(蓝圆↑) / 转向(蓝底弯箭头) / 停车(红圈白杠) / 注意行人(黄三角)

答题时留意阈值滑杆:把它推到 0.90 后再抽 5 题——现实中过高的置信度门槛会让 "注意行人"这类小目标最先漏检;推到 0.30 又会把阴影当成"停车"。0.45~0.65 是本沙盘的甜点区。

08常见问题

Q 红灯常被认成绿灯?
红 H 环抱 0°/180°:两个窗口都要开(0-10 与 170-180);再把 S 下限提到 60 排除白反光。
Q 接近 0.3m 画面突然花?
HP60C 0.5m 近盲区边缘:识别机位保持 0.3~0.8m,别把相机怼到灯上标定。
Q /traffic/light 一直闪?
缺三帧稳定滤波,或曝光在频繁抖:锁定曝光参考帧 + 连续 3 帧一致才发布。
Q NPU 推理没生效还是 CPU 跑?
查 rknpu2_server 是否加载了 rknn 文件;日志无 "model loaded" 或延迟 >100ms 即掉回 CPU。
Q 换灯后全部失灵?
按验收流程 5 分钟重标定:三态各截一帧 → trackbar 重拖 → 存 hsv_config.yaml,别改代码。
Q 置信度调到多少合适?
以 PR 曲线拐点为锚,本沙盘经验值 0.55;四类样本不均衡时按"注意行人"召回率定下限。
Q 检测帧率掉到 5Hz?
NPU 被占或分辨率过大:640→416 降档;确认无其他模型进程抢占。
Q /traffic/sign 没消费方?
正常——EXP-01 阶段它只是生产者;EXP-03 状态机上线后才会被订阅,先用 echo 验收。

09拓展阅读

  • OpenCV 官方 HSV 教程:inRange + morphologyEx 开闭运算的标准姿势——本课灯态节点的全部原型。
  • rknn-toolkit2 文档:INT8 量化校准集怎么选(本课:三光照 × 200 张)——校准集差,mAP 掉一半的故事每天都在发生。
  • YOLOv8 官方仓库:--conf/--iou 推理参数与 PR 曲线绘制,配合本页互动面板的阈值直觉一起看。
  • C1 产品页:6 TOPS NPU 与 HP60C 规格原始口径(仓库 products/c1-car)。
  • 上一实验:EXP-01 的语义点位——灯口坐标就是本实验相机预置机位的取点来源。

10思考题 · 自测

✅ 完成成果
/traffic/light 三态 20 轮 ≥95% + /traffic/sign 四类三距离全检出 + 重标定 ≤5 分钟。
🧠 原理收获
讲清 HSV 选型理由、三帧稳定的作用、INT8 校准集与 mAP 的关系。
🛠 技能收获
独立完成 HSV 标定、RKNN 转换部署、阈值-置信度双调优一轮完整回归。
📐 评分速览
灯态准确率 35% + 标志检出 35% + 重标定效率 20% + 话题规范 10%。
思考 1为什么灯态判定要"三帧一致"而标志检测每帧即发?两类输出的下游消费方式(状态机 vs 改道决策)有何不同,导致了这种差异?
思考 2若把识别距离压到 0.3m 以内会发生什么?结合 HP60C 近盲区与透镜最小对焦距离,说明"感知硬件约束如何反过来规定战术动作"。