4. 高精地图制作流程:数据采集→点云配准→语义分割→要素提取→拓扑构建→质量检查,全链路详解

做高精地图这么多年,我经常被问到:「你们到底是怎么把一堆点云变成自动驾驶能用的地图的?」

说实话,这问题问到了根上。高精地图的制作,不是简单的画图,而是一条完整的工业化流水线。今天我就把这套流程掰开揉碎了讲给你听。

4.1 数据采集:一切的基础

数据采集是第一步,也是最容易被低估的一步。我见过太多项目,算法调得再好,采集的数据不行,后面全白搭。

主流方案是激光雷达+惯导+轮速计的组合。激光雷达负责「看」,惯导和轮速计负责「定位」。这里有个关键点:采集车的标定必须做扎实

⚠️ 我曾经踩过的坑: 有一次采集车换了轮胎没重新标定轮速计,结果跑了200公里数据,回来一看里程误差超过5%。那批数据直接废了,白白浪费了两周时间。

数据采集的典型配置如下:

传感器 型号举例 关键参数
激光雷达 Hesai Pandar64 / Ouster OS1-64 线数≥64,帧率10Hz
惯导 NovAtel PwrPak7 / iXblue 陀螺零偏稳定性≤0.01°/h
轮速计 ABS轮速传感器 脉冲数≥100/转

采集时要注意天气。雨天点云会有大量噪点,雪天路面反射率变化大。我个人习惯是选择晴朗、干燥的天气作业,数据质量最稳定。

4.2 点云配准:把碎片拼成完整画面

采集车跑一圈,得到的是无数帧点云。每帧都是独立的「碎片」,配准就是把这些碎片拼成一张完整的大图。

配准的核心算法是ICP(迭代最近点)及其变种。但纯ICP容易陷入局部最优,所以实际工程中会用两步走:

  1. 粗配准:利用GPS/IMU提供的初始位姿,把点云大致对齐
  2. 精配准:用NDT(正态分布变换)或GICP做精细调整

这里有个技巧:不要对所有点云做全局配准。计算量太大,而且容易漂移。我建议用滑动窗口法,每次只配准相邻的10-20帧,然后通过图优化把误差分摊到全局。

🔑 关键参数: 配准的收敛阈值一般设为0.01m,迭代次数上限50次。如果超过50次还不收敛,大概率是初始位姿太差,需要检查IMU数据。

4.3 语义分割:让机器看懂点云

配准完的点云是一堆三维坐标点,机器不知道哪个点是路面、哪个是护栏、哪个是车道线。语义分割就是给每个点打标签。

现在主流方案是深度学习,比如PointNet++、RandLA-Net。我项目里用得最多的是RandLA-Net,因为它效率高,能处理大规模点云。

训练数据是关键。我建议至少准备10万帧标注好的点云,覆盖不同场景:城市道路、高速公路、隧道、桥梁等。标注类别一般包括:

  • 路面(road surface)
  • 车道线(lane marking)
  • 路沿(curb)
  • 护栏(guardrail)
  • 交通标志牌(traffic sign)
  • 杆状物(pole)
  • 建筑物(building)

嗯,这里要注意:类别不要太多。我见过有人分了50多个类别,结果模型精度一塌糊涂。高精地图只需要关注对驾驶决策有影响的要素,其他的一律归为「背景」。

4.4 要素提取:从语义到几何

语义分割完,我们有了带标签的点云。但自动驾驶需要的是精确的几何信息——车道线的位置、路沿的高度、标志牌的中心点。要素提取就是干这个的。

以车道线提取为例,流程是这样的:

  1. 从语义分割结果中筛选出「车道线」类别的点
  2. 用RANSAC拟合直线或曲线
  3. 计算车道线的宽度、曲率、起点终点坐标
  4. 输出为矢量格式(如GeoJSON)

代码示例(伪代码):

def extract_lane_marking(points_with_labels):
    # 筛选车道线点
    lane_points = [p for p in points_with_labels if p.label == 'lane_marking']
    
    # RANSAC拟合
    model = RANSAC()
    model.fit(lane_points)
    
    # 输出矢量
    return {
        'type': 'LineString',
        'coordinates': model.get_control_points(),
        'width': model.get_width(),
        'curvature': model.get_curvature()
    }

💡 我的经验: 车道线提取最容易出错的地方是「虚线」和「实线」的区分。虚线有间隔,RANSAC容易把一段虚线拆成多段。我后来加了一个后处理步骤:把距离小于0.5m的线段合并,效果好了很多。

4.5 拓扑构建:让地图「活」起来

要素提取完,我们有了车道线、路沿、标志牌等元素。但它们还是孤立的。拓扑构建就是把这些元素连接成一张网络,让自动驾驶系统知道「从哪里来、到哪里去」。

拓扑的核心是车道连接关系。每个车道都有:

  • 前驱车道(predecessor)
  • 后继车道(successor)
  • 左邻车道(left neighbor)
  • 右邻车道(right neighbor)

构建拓扑的算法其实不复杂:

  1. 根据车道线的几何走向,判断车道之间的前后连接
  2. 根据车道线的左右距离,判断邻接关系
  3. 在交叉口处,根据转向规则建立连接

你想想看,如果拓扑构建错了,自动驾驶车到了路口就不知道往哪拐。我遇到过最离谱的一次,拓扑把左转车道连到了直行车道,测试车在路口直接懵了,原地打转。

4.6 质量检查:最后的防线

最后一步,也是最重要的一步——质量检查。没有质检的高精地图,就是一颗定时炸弹。

质检分三个层面:

检查层级 检查内容 通过标准
几何精度 车道线位置误差、路沿高度误差 绝对误差≤0.1m,相对误差≤0.05m
拓扑一致性 车道连接是否闭环、是否有断头路 100%连通,无孤立车道
语义正确性 车道类型、限速值、转向规则 与现场一致,抽检合格率≥99.5%

⚠️ 避坑指南: 我曾经因为赶工期,跳过了拓扑一致性检查。结果地图上线后,车辆在一条高架路上连续遇到3个断头路,系统直接降级为L2。从那以后,我定了一条铁律:质检不过,绝不发布

自动化质检工具可以跑80%的检查项,但剩下的20%必须人工复核。我建议每10公里地图至少安排1个人工抽检点,重点检查交叉口、匝道、隧道出入口这些复杂场景。

4.7 全链路总结

好了,整个流程走下来,你会发现高精地图制作其实是一个「数据→信息→知识」的转化过程。数据采集是原料,点云配准是清洗,语义分割是分类,要素提取是结构化,拓扑构建是知识化,质量检查是保障。

每个环节都有坑,但只要你把每个环节的标准定死、流程固化,就能做出稳定可靠的高精地图。说白了,这行没有捷径,只有把每个细节做到位。

下一章我会讲差分更新技术——地图做出来只是开始,怎么让它保持新鲜才是真正的挑战。