第3章:自动驾驶数据集与标注规范
做自动驾驶感知,说白了就是教模型看懂路。但模型怎么学?靠数据喂。数据怎么喂?靠标注规范。
我入行那会儿,第一个项目就是做目标检测。当时团队自己标数据,标得那叫一个痛苦。后来接触了KITTI、BDD100K这些公开数据集,才明白什么叫「专业的事交给专业的人」。今天我就把这三个主流数据集和标注规范掰开揉碎讲清楚。
3.1 三大主流数据集:KITTI、BDD100K、Waymo
先说说这三个数据集各自的特点。嗯,它们就像三个性格迥异的老师傅,各有各的绝活。
3.1.1 KITTI数据集
KITTI是德国卡尔斯鲁厄理工学院和丰田美国研究院搞的。2012年发布,算是自动驾驶界的「老前辈」了。我个人习惯拿它做算法验证,因为数据量适中,标注质量高。
- 数据规模:约15GB,包含市区、乡村、高速公路等场景
- 传感器配置:1个双目相机 + 1个64线激光雷达 + GPS/IMU
- 标注内容:2D框、3D框、跟踪ID、遮挡/截断属性
- 类别:Car、Pedestrian、Cyclist 等8类
我在项目中遇到过一个问题:KITTI的标注是「前向视角」的,也就是说只有车前方的目标。如果你要做360度感知,得自己想办法补全其他方向的数据。
KITTI的3D框标注格式:
# 类型 截断 遮挡 观察角 2D框 3D尺寸 3D位置 旋转角 置信度
Car 0.0 0 1.85 387.63 181.54 423.17 203.09 1.53 1.63 3.48 -1.56 1.57 0.0 0.0 0.0
3.1.2 BDD100K数据集
BDD100K是伯克利大学搞的。2018年发布,主打「多样性」。为什么这么说?因为它包含了不同天气、不同时段、不同地点的数据。
- 数据规模:100K张图片,约1.8TB(含视频)
- 场景覆盖:白天/夜晚/黄昏、晴天/雨天/雪天、城市/乡村/高速
- 标注内容:2D框、可行驶区域、车道线、实例分割
- 类别:10大类(Car、Bus、Truck、Person等)
你想想看,如果你的模型只在KITTI上训练,到了雨雪天可能就「瞎」了。BDD100K正好补上这个短板。我建议做量产项目时,至少混入30%的BDD100K数据,能显著提升鲁棒性。
小技巧:BDD100K的标注是JSON格式,和COCO很像。但注意它的「truncated」字段是0-1的浮点数,不是KITTI的0/1/2整数。转换格式时别搞混了。
3.1.3 Waymo Open Dataset
Waymo是谷歌旗下的自动驾驶公司。2019年开源的数据集,是目前规模最大、标注最精细的之一。我记得第一次打开Waymo数据时,被它的传感器配置惊到了——5个激光雷达 + 5个相机,覆盖360度无死角。
- 数据规模:约2000个场景,每个场景20秒,共约12TB
- 传感器配置:5个激光雷达 + 5个相机(前、左前、右前、左、右)
- 标注内容:2D框、3D框、跟踪ID、速度、加速度
- 类别:Vehicle、Pedestrian、Cyclist、Sign 等4大类
Waymo的标注有个特点:它把「遮挡」分成了0(完全可见)、1(部分遮挡)、2(大部分遮挡)三个等级。这个粒度比KITTI更细。我在做遮挡感知模型时,就喜欢用Waymo的数据来训练。
注意:Waymo数据集的TFRecord格式比较特殊。如果你用PyTorch,需要先转成pickle或h5py格式。我曾经因为没处理好数据加载,白白浪费了两天时间。
3.2 COCO格式与自动驾驶标注的特殊要求
COCO格式是计算机视觉领域最通用的标注格式之一。但自动驾驶场景有些特殊要求,不能直接套用。
3.2.1 COCO格式基础
COCO格式的核心是JSON文件,包含以下几个字段:
{
"images": [{"id": 1, "file_name": "000001.jpg", "width": 1920, "height": 1080}],
"annotations": [
{
"id": 1,
"image_id": 1,
"category_id": 3,
"bbox": [100, 200, 50, 80], // [x, y, width, height]
"area": 4000,
"segmentation": [...],
"iscrowd": 0
}
],
"categories": [{"id": 3, "name": "car"}]
}
说白了,COCO格式就是一套标准化的「数据字典」。但自动驾驶场景有三大特殊要求:遮挡、截断、2D/3D框。
3.2.2 遮挡(Occlusion)
遮挡是自动驾驶中最头疼的问题。一辆车被另一辆车挡住一半,模型怎么判断?
- KITTI方式:0=完全可见,1=部分遮挡,2=大部分遮挡,3=未知
- Waymo方式:0=完全可见,1=部分遮挡,2=大部分遮挡
- BDD100K方式:0=无遮挡,1=有遮挡
我个人习惯用KITTI的4级标注。因为「部分遮挡」和「大部分遮挡」对模型的影响差别很大。举个例子:一辆车被挡住30%和挡住70%,模型需要的特征完全不同。
避坑指南:我曾经在标注时把「遮挡」和「截断」搞混了。遮挡是目标被其他物体挡住,截断是目标超出图像边界。这两个属性要分开标注,不能混为一谈。
3.2.3 截断(Truncation)
截断指的是目标有一部分在图像外面。比如一辆车只露出半个车头。
- KITTI方式:0=无截断,1=有截断(二值化)
- BDD100K方式:0.0~1.0的浮点数,表示截断比例
- Waymo方式:不单独标注截断,用2D框边界判断
我建议用BDD100K的浮点数方式。因为「截断10%」和「截断80%」的处理策略完全不同。截断10%的物体,模型还能靠上下文推断;截断80%的,基本只能靠「猜」了。
3.2.4 2D框与3D框
2D框是矩形框,标注的是目标的「视觉范围」。3D框是立方体框,标注的是目标的「物理空间」。两者缺一不可。
| 维度 | 2D框 | 3D框 |
|---|---|---|
| 表示方式 | [x, y, w, h] | [x, y, z, l, w, h, yaw] |
| 坐标系 | 图像像素坐标系 | 相机/激光雷达坐标系 |
| 用途 | 检测、跟踪 | 定位、规划、控制 |
| 标注难度 | 低(人工可标) | 高(需激光雷达辅助) |
你想想看,2D框只能告诉你「那里有辆车」,但3D框能告诉你「车离你多远、朝向哪、占多大空间」。做自动驾驶,3D框是刚需。
经验之谈:标注3D框时,注意「yaw角」的定义。KITTI用的是「观察角」,Waymo用的是「朝向角」。两者差了一个相机视角的偏移量。我刚开始做3D检测时,就因为搞混了这两个角,模型训练了三天结果全是错的。
3.3 标注规范总结
好了,说了这么多,我总结一下核心要点:
- 数据集选择:KITTI适合算法验证,BDD100K适合鲁棒性提升,Waymo适合量产级模型训练
- 遮挡标注:建议用4级(0-3),区分「部分」和「大部分」遮挡
- 截断标注:建议用浮点数(0.0-1.0),精确表示截断比例
- 2D/3D框:两者都要标,2D框用于视觉检测,3D框用于空间定位
- 格式转换:不同数据集格式不同,注意字段含义的差异
最后说一句:标注规范决定了模型的天花板。数据标得烂,模型再牛也白搭。我见过太多团队花大价钱买数据,结果标注质量一塌糊涂,模型训练出来根本没法用。嗯,这章就到这儿,下一章我们聊聊YOLO模型在自动驾驶中的具体落地技巧。