4. 高精地图制作流程:数据采集→点云配准→语义分割→要素提取→拓扑构建→质量检查,全链路详解
做高精地图这么多年,我经常被问到:「你们到底是怎么把一堆点云变成自动驾驶能用的地图的?」
说实话,这问题问到了根上。高精地图的制作,不是简单的画图,而是一条完整的工业化流水线。今天我就把这套流程掰开揉碎了讲给你听。
4.1 数据采集:一切的基础
数据采集是第一步,也是最容易被低估的一步。我见过太多项目,算法调得再好,采集的数据不行,后面全白搭。
主流方案是激光雷达+惯导+轮速计的组合。激光雷达负责「看」,惯导和轮速计负责「定位」。这里有个关键点:采集车的标定必须做扎实。
数据采集的典型配置如下:
| 传感器 | 型号举例 | 关键参数 |
|---|---|---|
| 激光雷达 | Hesai Pandar64 / Ouster OS1-64 | 线数≥64,帧率10Hz |
| 惯导 | NovAtel PwrPak7 / iXblue | 陀螺零偏稳定性≤0.01°/h |
| 轮速计 | ABS轮速传感器 | 脉冲数≥100/转 |
采集时要注意天气。雨天点云会有大量噪点,雪天路面反射率变化大。我个人习惯是选择晴朗、干燥的天气作业,数据质量最稳定。
4.2 点云配准:把碎片拼成完整画面
采集车跑一圈,得到的是无数帧点云。每帧都是独立的「碎片」,配准就是把这些碎片拼成一张完整的大图。
配准的核心算法是ICP(迭代最近点)及其变种。但纯ICP容易陷入局部最优,所以实际工程中会用两步走:
- 粗配准:利用GPS/IMU提供的初始位姿,把点云大致对齐
- 精配准:用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 要素提取:从语义到几何
语义分割完,我们有了带标签的点云。但自动驾驶需要的是精确的几何信息——车道线的位置、路沿的高度、标志牌的中心点。要素提取就是干这个的。
以车道线提取为例,流程是这样的:
- 从语义分割结果中筛选出「车道线」类别的点
- 用RANSAC拟合直线或曲线
- 计算车道线的宽度、曲率、起点终点坐标
- 输出为矢量格式(如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)
构建拓扑的算法其实不复杂:
- 根据车道线的几何走向,判断车道之间的前后连接
- 根据车道线的左右距离,判断邻接关系
- 在交叉口处,根据转向规则建立连接
你想想看,如果拓扑构建错了,自动驾驶车到了路口就不知道往哪拐。我遇到过最离谱的一次,拓扑把左转车道连到了直行车道,测试车在路口直接懵了,原地打转。
4.6 质量检查:最后的防线
最后一步,也是最重要的一步——质量检查。没有质检的高精地图,就是一颗定时炸弹。
质检分三个层面:
| 检查层级 | 检查内容 | 通过标准 |
|---|---|---|
| 几何精度 | 车道线位置误差、路沿高度误差 | 绝对误差≤0.1m,相对误差≤0.05m |
| 拓扑一致性 | 车道连接是否闭环、是否有断头路 | 100%连通,无孤立车道 |
| 语义正确性 | 车道类型、限速值、转向规则 | 与现场一致,抽检合格率≥99.5% |
⚠️ 避坑指南: 我曾经因为赶工期,跳过了拓扑一致性检查。结果地图上线后,车辆在一条高架路上连续遇到3个断头路,系统直接降级为L2。从那以后,我定了一条铁律:质检不过,绝不发布。
自动化质检工具可以跑80%的检查项,但剩下的20%必须人工复核。我建议每10公里地图至少安排1个人工抽检点,重点检查交叉口、匝道、隧道出入口这些复杂场景。
4.7 全链路总结
好了,整个流程走下来,你会发现高精地图制作其实是一个「数据→信息→知识」的转化过程。数据采集是原料,点云配准是清洗,语义分割是分类,要素提取是结构化,拓扑构建是知识化,质量检查是保障。
每个环节都有坑,但只要你把每个环节的标准定死、流程固化,就能做出稳定可靠的高精地图。说白了,这行没有捷径,只有把每个细节做到位。
下一章我会讲差分更新技术——地图做出来只是开始,怎么让它保持新鲜才是真正的挑战。