3. 语义分割核心概念

在可行驶区域与道路语义分割工程中,模型真正要回答的问题并不是“图里有什么”,而是“图中每一个像素分别属于什么类别”。这与目标检测用矩形框圈出对象、实例分割再区分个体不同:语义分割的输出是一张与输入图像同尺寸的类别图,每个像素被赋予一个类别编号。理解像素级分类、类别定义与标签体系,是后续数据标注、模型训练和指标评估的共同语言。

一、像素级分类的本质

给定一张 H×W×3 的输入图像,语义分割网络输出 H×W×C 的类别得分张量,C 为类别数。对每个像素位置 (i,j),在 C 个通道上做 softmax 或 argmax,得到该像素的预测类别。因此语义分割可以看作“对每个像素做一次分类”,只是这些分类共享同一套卷积特征,像素之间通过上下文相互影响。

与检测框相比,像素级分类带来三个工程特性:其一,输出是稠密的,边界处的误差会直接体现为区域侵入或缺失;其二,类别不区分同一类别的不同个体,两辆车相邻时会被预测为同一片“车辆”区域;其三,类别定义一旦确定,标注、损失函数、评估指标都必须围绕同一套编号体系展开,任何不一致都会造成训练信号错乱。

核心公式:预测类别图 = argmaxc fθ(x)[i,j,c],其中 c ∈ {0,1,…,C−1},0 通常保留给背景或忽略类。

二、类别定义与标签体系

可行驶区域分割的标签体系通常按“道路结构—交通参与者—环境与设施—忽略类”四层组织。类别定义需要同时满足三个约束:语义上互斥、工程上可标注、下游任务可消费。例如“可行驶区域”和“道路”并不等价:前者强调车辆当前能否安全通行,后者强调道路这一物理结构;在施工、积水、锥桶围挡场景中,二者会出现明显差异。

下面给出一套典型的道路语义标签体系,类别编号从 0 开始,0 保留为忽略类,便于在损失函数中屏蔽不确定像素。

编号类别名语义说明典型颜色
0ignore / unlabeled不确定、遮挡、天空边缘等不参与损失黑
1drivable当前可安全行驶的路面区域青绿
2road道路结构面,含暂不可行驶部分深灰
3lane_marking车道线、导流线、停止线白
4curb路缘石、路肩边界橙
5sidewalk人行道、非机动车道浅紫
6vehicle机动车、非机动车等交通参与者红
7pedestrian行人、骑行者黄
8obstacle锥桶、水马、施工围挡等临时障碍品红
9vegetation树木、绿化带绿
10sky天空蓝

类别定义不是越细越好。类别过细会带来标注成本上升、类间边界模糊、长尾类别样本不足等问题;类别过粗则无法支撑下游的避障与路径规划。工程上常采用“基础类别 + 可合并映射”的方式:标注阶段保留细类,训练阶段按任务需要合并为 drivable / non-drivable 或 drivable / obstacle / other 等粗类。

三、可行驶区域与道路语义的关系

可行驶区域(drivable area)是道路语义的一个子集,但二者在标注逻辑上存在方向性差异。道路语义回答“这个像素在物理上属于什么”,可行驶区域回答“这个像素当前是否可通行”。前者相对稳定,后者随交通参与者、临时障碍、天气与光照变化而动态改变。

因此,在标签体系中通常把 drivable 作为独立类别,而不是简单从 road 中减去 vehicle 和 obstacle。原因在于:被车辆遮挡的路面在物理上仍是道路,但在当前时刻不可行驶;如果仅用 road 减去 vehicle,模型会学到“车辆所在位置不是道路”的错误先验,导致车辆驶离后该区域无法恢复为可行驶。正确做法是让模型同时学习 road 与 drivable 两个通道,由下游逻辑决定优先级。

像素级分类与标签体系:从图像到类别图 输入图像 H × W × 3 RGB 像素矩阵 道路场景实拍 分割网络 编码器 + 解码器 输出 H × W × C 得分 逐像素 argmax 类别图 H × W × 1 每像素一个类别编号 0 ~ C−1 下游 路径规划 避障决策 可行驶判断 标签体系四层结构 道路结构 road / drivable / curb 交通参与者 vehicle / pedestrian 环境与设施 vegetation / sky / obstacle 忽略类 ignore / unlabeled 道路语义 road 物理结构面,相对稳定 包含被遮挡、暂不可通行部分 不随交通参与者动态变化 可行驶区域 drivable 当前时刻可安全通行的像素集合 受障碍、施工、天气影响 是 road 的动态子集,需独立建模

四、方法流程:从标注到训练

标签体系确定后,工程流程通常按以下步骤推进:

  1. 定义类别清单与编号,写入 label_config.json,作为标注、训练、评估的唯一来源。
  2. 按类别编写标注规范,明确边界像素归属规则,例如路缘石归 curb 还是 road。
  3. 使用标注工具生成单通道 PNG 或索引图,像素值即类别编号。
  4. 训练时读取索引图,按 ignore 掩码计算交叉熵或 Dice 损失。
  5. 评估时按类别计算 IoU,重点关注 drivable、obstacle、pedestrian 等安全相关类别。
{
  "num_classes": 11,
  "ignore_index": 0,
  "classes": [
    "ignore", "drivable", "road", "lane_marking", "curb",
    "sidewalk", "vehicle", "pedestrian", "obstacle",
    "vegetation", "sky"
  ],
  "merge_map": {
    "drivable_binary": {"drivable": 1, "others": 0}
  }
}

五、案例与常见误区

某园区低速无人车项目最初只标注 road 与 vehicle 两类,训练后发现车辆驶离后原位置仍被预测为不可行驶。复盘发现,标注员把被车辆遮挡的路面直接标成了 vehicle,模型学到了“车辆位置等于非道路”的错误关联。修正方案是引入 drivable 独立类别,并要求遮挡区域按道路结构补标,同时用 ignore 标记完全无法判断的像素。

常见误区一:把可行驶区域等同于道路,忽略动态障碍与临时施工。误区二:类别编号在标注、训练、评估三处不一致,导致损失计算错位。误区三:忽略类使用不当,把大量难例直接丢进 ignore,模型在关键区域缺乏监督。误区四:类别过细但样本极少,长尾类别 IoU 长期为零,拖累整体指标。
实践建议:先用 5~8 个基础类别跑通全流程,再根据下游需求逐步细分;每次调整类别体系都要同步更新标注规范、配置文件与评估脚本,并保留版本记录,避免标签漂移。

像素级分类、类别定义与标签体系三者构成语义分割工程的地基。只有把“每个像素属于什么”这件事定义清楚、标注一致、训练与评估对齐,可行驶区域与道路语义分割的结果才具备工程可用性。