4、数据标注与真值生成:标注工具、自动标注与真值验证

数据标注这件事,说白了就是给传感器数据「打标签」。

我刚开始做ADAS路采时,总觉得算法模型才是核心。后来被现实狠狠教育了一课——没有高质量的真值,再牛的模型也是空中楼阁。你想想看,模型学到的上限,就是标注质量的上限。

4.1 标注工具选型:从2D到3D

标注工具这块,我踩过不少坑。先说说最常见的几款。

4.1.1 LabelImg:2D图像标注的入门首选

LabelImg是我个人最早接触的工具。它轻量、开源,适合小规模验证。

  • 支持格式:Pascal VOC(XML)、YOLO(TXT)
  • 标注类型:矩形框、多边形
  • 快捷键:W(创建框)、D(下一张)、A(上一张)

我在项目中遇到过一个问题:LabelImg对超大分辨率图像处理很慢。后来我改用它的「自动保存」功能,每标一张就存一次,避免崩溃丢数据。

小技巧:LabelImg的「自动保存间隔」建议设为1。别问我怎么知道的——有一次标了200张没保存,软件崩了,我差点把电脑砸了。

4.1.2 CVAT:团队协作的利器

CVAT是Intel开源的在线标注平台。说实话,它比LabelImg强大太多。

特性 LabelImg CVAT
部署方式 本地单机 Web服务/本地Docker
多人协作 不支持 支持
标注类型 2D框 2D框、多边形、关键点、3D
自动标注 内置深度学习模型

我记得有一次团队要标注5000张夜间场景。用LabelImg的话,一个人得干两周。换成CVAT后,三个人并行标注,配合自动追踪功能,三天搞定。

注意:CVAT的Docker部署需要至少8GB内存。我曾经在4GB的笔记本上跑,结果卡到怀疑人生。

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之间的框。

经验之谈:自动标注的召回率可以设高一点(比如0.3),宁可多标错,不要漏标。因为人工修正漏标比修正错标要麻烦得多。

4.2.2 3D点云自动标注:BEV视角的妙用

点云自动标注比2D复杂得多。我推荐一个思路:将点云投影到BEV(鸟瞰图),然后在BEV上做2D检测,再反投影回3D空间。

具体步骤:

  1. 将点云投影到BEV图像(分辨率建议0.1m/pixel)
  2. 用2D检测模型在BEV上检测目标
  3. 将2D框转换为3D边界框(需要知道目标高度)
  4. 用ICP算法微调3D框的位置

我曾经用这个方法处理了10万帧点云数据。自动标注的准确率大概在70%左右,剩下的30%需要人工修正。但即便如此,也比纯手工标注快了5倍。

避坑指南:自动标注的结果一定要做「一致性检查」。比如同一辆车在连续帧中突然消失又出现,这大概率是标注错了。我写过一个脚本,专门检测这种「鬼影」现象。

4.3 真值验证流程:别让垃圾数据毁了你的模型

标注完了就完事了?太天真了。真值验证才是决定模型上限的关键环节。

我见过太多团队,标注了10万帧数据,结果模型训练效果还不如用5万帧精心验证的数据。为什么?因为标注错误会「教坏」模型。

4.3.1 验证流程三步走

我个人习惯用这套流程:

  1. 自动检查:用规则引擎过滤明显错误
    • 框超出图像边界 → 自动删除
    • 框面积小于10像素 → 标记为可疑
    • 同一目标出现两个框 → 合并或删除
  2. 抽样人工审核:按场景类型分层抽样
    • 白天场景:抽5%
    • 夜间场景:抽10%
    • 雨雾场景:抽20%
  3. 交叉验证:两个标注员互检
    • 计算IoU(交并比)
    • IoU < 0.7 → 人工仲裁

4.3.2 真值质量评估指标

我常用这几个指标来量化真值质量:

指标 计算公式 合格标准
标注准确率 正确标注数 / 总标注数 > 95%
漏标率 漏标目标数 / 实际目标数 < 3%
框质量 平均IoU(与标准框) > 0.85
一致性 连续帧框的IoU变化 变化 < 0.2

我记得有一次,一个标注团队交上来的数据「准确率」显示98%。但我一查「一致性」指标,发现很多框在连续帧中跳来跳去。后来发现是标注员偷懒,只标了关键帧,中间帧用插值糊弄过去了。

我的建议:真值验证不是一次性工作。我习惯在标注过程中做「中期检查」——标到30%时抽检一次,60%时再抽检一次。发现问题及时纠正,比到最后返工要省心得多。

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的数据管得井井有条。