4、数据标注与真值生成:标注工具、自动标注与真值验证
数据标注这件事,说白了就是给传感器数据「打标签」。
我刚开始做ADAS路采时,总觉得算法模型才是核心。后来被现实狠狠教育了一课——没有高质量的真值,再牛的模型也是空中楼阁。你想想看,模型学到的上限,就是标注质量的上限。
4.1 标注工具选型:从2D到3D
标注工具这块,我踩过不少坑。先说说最常见的几款。
4.1.1 LabelImg:2D图像标注的入门首选
LabelImg是我个人最早接触的工具。它轻量、开源,适合小规模验证。
- 支持格式:Pascal VOC(XML)、YOLO(TXT)
- 标注类型:矩形框、多边形
- 快捷键:W(创建框)、D(下一张)、A(上一张)
我在项目中遇到过一个问题:LabelImg对超大分辨率图像处理很慢。后来我改用它的「自动保存」功能,每标一张就存一次,避免崩溃丢数据。
4.1.2 CVAT:团队协作的利器
CVAT是Intel开源的在线标注平台。说实话,它比LabelImg强大太多。
| 特性 | LabelImg | CVAT |
|---|---|---|
| 部署方式 | 本地单机 | Web服务/本地Docker |
| 多人协作 | 不支持 | 支持 |
| 标注类型 | 2D框 | 2D框、多边形、关键点、3D |
| 自动标注 | 无 | 内置深度学习模型 |
我记得有一次团队要标注5000张夜间场景。用LabelImg的话,一个人得干两周。换成CVAT后,三个人并行标注,配合自动追踪功能,三天搞定。
4.1.3 点云标注:3D世界的挑战
点云标注和2D图像完全是两码事。你想想看,几万个点飘在三维空间里,要从中框出一辆车——这难度不是一个量级。
常用的点云标注工具有:
- SUSTech POINTS:开源,支持BEV和3D视图联动
- LATTE:百度开源,支持点云+图像融合标注
- PointCloud Lab:轻量级,适合小规模数据
我个人习惯用SUSTech POINTS。它的「自动插值」功能很实用——你只需要标关键帧,中间帧它会自动生成。嗯,这里要注意:自动插值的结果一定要人工复核,我遇到过插值把车标到人行道上的情况。
4.2 自动标注:用预训练模型解放双手
纯手工标注?那是2018年的玩法了。现在大家都在用自动标注。
自动标注的核心思路很简单:用预训练模型先跑一遍,人工再修正。说白了就是「机器打底稿,人来精修」。
4.2.1 2D自动标注:基于检测模型
我常用的方案是YOLOv8 + 半自动标注流程:
# 伪代码示例:自动标注流程
from ultralytics import YOLO
# 加载预训练模型
model = YOLO('yolov8x.pt')
# 批量推理
results = model.predict(
source='./raw_images/',
save=True,
save_txt=True, # 保存为标注格式
conf=0.5 # 置信度阈值
)
# 输出格式:class_id x_center y_center width height
# 例如:0 0.5 0.5 0.2 0.3 (car)
我在项目中遇到过一个问题:模型对「异形车」的检测率很低。比如那种加长货车、工程车,模型经常漏检。我的解决办法是:先用自动标注跑一遍,然后人工重点检查置信度在0.3-0.7之间的框。
4.2.2 3D点云自动标注:BEV视角的妙用
点云自动标注比2D复杂得多。我推荐一个思路:将点云投影到BEV(鸟瞰图),然后在BEV上做2D检测,再反投影回3D空间。
具体步骤:
- 将点云投影到BEV图像(分辨率建议0.1m/pixel)
- 用2D检测模型在BEV上检测目标
- 将2D框转换为3D边界框(需要知道目标高度)
- 用ICP算法微调3D框的位置
我曾经用这个方法处理了10万帧点云数据。自动标注的准确率大概在70%左右,剩下的30%需要人工修正。但即便如此,也比纯手工标注快了5倍。
4.3 真值验证流程:别让垃圾数据毁了你的模型
标注完了就完事了?太天真了。真值验证才是决定模型上限的关键环节。
我见过太多团队,标注了10万帧数据,结果模型训练效果还不如用5万帧精心验证的数据。为什么?因为标注错误会「教坏」模型。
4.3.1 验证流程三步走
我个人习惯用这套流程:
- 自动检查:用规则引擎过滤明显错误
- 框超出图像边界 → 自动删除
- 框面积小于10像素 → 标记为可疑
- 同一目标出现两个框 → 合并或删除
- 抽样人工审核:按场景类型分层抽样
- 白天场景:抽5%
- 夜间场景:抽10%
- 雨雾场景:抽20%
- 交叉验证:两个标注员互检
- 计算IoU(交并比)
- IoU < 0.7 → 人工仲裁
4.3.2 真值质量评估指标
我常用这几个指标来量化真值质量:
| 指标 | 计算公式 | 合格标准 |
|---|---|---|
| 标注准确率 | 正确标注数 / 总标注数 | > 95% |
| 漏标率 | 漏标目标数 / 实际目标数 | < 3% |
| 框质量 | 平均IoU(与标准框) | > 0.85 |
| 一致性 | 连续帧框的IoU变化 | 变化 < 0.2 |
我记得有一次,一个标注团队交上来的数据「准确率」显示98%。但我一查「一致性」指标,发现很多框在连续帧中跳来跳去。后来发现是标注员偷懒,只标了关键帧,中间帧用插值糊弄过去了。
4.3.3 一个实用的验证脚本
这是我写的一个简单验证脚本,用来检查标注框的合理性:
def validate_annotation(annotation):
"""
验证单个标注的有效性
返回: (is_valid, reason)
"""
# 1. 检查框是否在图像内
if (x1 < 0 or y1 < 0 or
x2 > img_width or y2 > img_height):
return False, "框超出图像边界"
# 2. 检查框面积
area = (x2 - x1) * (y2 - y1)
if area < 10:
return False, "框面积过小"
# 3. 检查宽高比(车辆通常宽高比在0.5-2.0之间)
aspect_ratio = (x2 - x1) / (y2 - y1)
if aspect_ratio < 0.3 or aspect_ratio > 3.0:
return False, "宽高比异常"
return True, "通过"
这个脚本虽然简单,但能过滤掉大约5%的明显错误标注。你想想看,10万帧数据里省掉5000帧的返工量,这效率提升可不是一星半点。
好了,数据标注和真值生成这块就聊到这儿。下一章我们讲讲数据存储和管理——说白了就是怎么把这几百TB的数据管得井井有条。