传统SLAM建的地图是"几何地图"——只有空间结构信息,没有语义信息。机器人知道"那里有一个长方体",但不知道"那是一张桌子"。对于导航来说几何地图可能够用(知道哪里有障碍物就行),但对于更高层的任务——"去厨房拿一杯水"、"找到最近的椅子坐下去"——机器人必须理解环境中物体的含义。语义SLAM就是给地图加上语义信息的SLAM系统。

语义SLAM的价值不只是"更好看的地图"。语义信息对SLAM本身也有帮助:可以区分静态物体(墙壁、地板)和动态物体(行人、车辆),改善回环检测(用"门"、"消防栓"这些语义地标做匹配,比纯几何匹配更鲁棒),还能辅助数据关联(同一个语义类别的物体更容易建立对应关系)。

语义地图的表示方式

语义地图怎么表示,决定了后续所有处理的思路。

物体级语义地图把环境中的物体建模为独立的语义实体。每个物体有类别标签(椅子、桌子、门)和3D形状(包围盒、凸包、或精确mesh)。地图本质上是一个物体列表,每个物体有ID、类别、位姿和形状。

# 物体级语义地图的数据结构
class SemanticObject:
    id: int
    category: str          # "chair", "table", "door"
    pose: SE3              # 物体在地图中的位姿
    bounding_box: Box3D    # 3D包围盒
    confidence: float      # 检测置信度
    observations: list     # 历史观测列表

class SemanticMap:
    objects: dict[int, SemanticObject]
    def query_by_category(self, category):
        return [o for o in self.objects.values() if o.category == category]

像素级/点级语义地图给地图中的每个点或每个像素都标注语义类别。这种表示更精细,但数据量也大。常见实现是把语义标签"贴"到点云上——每个3D点除了XYZ坐标,还带一个语义标签。

占据栅格语义地图是2D占据栅格的扩展,每个栅格不只记录"是否被占据",还记录"被什么类别占据"。这种方法在机器人导航中用得很多,不同语义类别可以设置不同的通行规则(草地可以走,水坑不能走)。

语义标注的方法

给地图加语义标注,需要把传感器数据和语义识别结合起来。

视觉语义标注是最常见的方案。用深度学习模型(YOLO、Mask R-CNN、语义分割网络)对图像做语义识别,然后把2D语义信息投影到3D空间中。多帧观测同一个物体,语义标签可以投票融合,提高准确率。

# 视觉语义标注流程
def semantic_labeling(image, depth, camera_pose, seg_model):
    # 2D语义分割
    semantic_mask = seg_model.predict(image)
    # 投影到3D
    points_3d = depth_to_points(depth, camera_pose)
    # 给3D点标注语义
    for i, pixel in enumerate(semantic_mask):
        points_3d[i].semantic_label = pixel.class_id
    return points_3d

激光雷达语义标注是近几年的热点。用PointNet++、MinkowskiNet等3D深度学习网络直接对点云做语义分割。好处是不受光照影响,缺点是训练数据不如图像丰富。SemanticKITTI挑战赛推动了3D点云语义分割的发展。

视觉+激光联合标注效果最好。图像提供丰富的颜色和纹理信息用于识别,点云提供精确的3D位置信息。两者互补,标注结果比单一传感器更准确。

物体级SLAM——以物体为地标的SLAM

物体级SLAM是语义SLAM的一个重要分支。它不只把语义信息"贴"到几何地图上,而是把物体本身当作SLAM的地标(landmark)。

传统SLAM的地标是特征点,没有物理含义。物体级SLAM的地标是有语义含义的物体。好处有几个:地标更稳定(椅子比角点更不容易消失);地标更少但信息更丰富;可以在优化中同时估计相机位姿和物体位姿。

# 物体级SLAM的因子图
graph = FactorGraph()
# 相机位姿节点
for t in range(num_frames):
    graph.add_pose_node(f"cam_{t}")
# 物体位姿节点
for obj in detected_objects:
    graph.add_pose_node(f"obj_{obj.id}")
# 观测因子:相机观测到了某个物体
for obs in observations:
    graph.add_factor(f"cam_{obs.frame}", f"obj_{obs.object_id}", obs.measurement)

CubeSLAM和QuadricSLAM是物体级SLAM的代表工作。它们把物体建模为3D长方体,用2D检测框作为观测,在因子图中同时优化相机位姿和物体包围盒。这种方法输出的地图既有定位信息又有语义信息,对机器人的高层决策很有价值。

语义信息对SLAM的反馈

语义信息不只是SLAM的"输出",还可以反过来帮助SLAM做得更准。

辅助动态物体检测在前面聊过了。辅助回环检测也是重要应用——两个场景的几何结构可能相似(感知混叠),但语义内容不同(一个是办公室一个是走廊)。加入语义约束后,回环检测的误检率可以降低。

辅助数据关联是另一个应用。在SLAM中需要把不同帧观测到的同一个物体关联起来。如果两个物体都是"椅子"且位置接近,它们很可能是同一个物体。语义类别提供了很强的先验信息,让数据关联更准确。

# 语义辅助的数据关联
def semantic_data_association(detected_obj, map_objects):
    candidates = []
    for map_obj in map_objects:
        if map_obj.category == detected_obj.category:  # 语义一致
            dist = distance(map_obj.pose, detected_obj.pose)
            if dist < threshold:  # 距离接近
                candidates.append((map_obj, dist))
    return min(candidates, key=lambda x: x[1]) if candidates else None

面试追问环节

面试官:语义SLAM和传统SLAM的区别是什么?

传统SLAM输出的是几何地图——点云、mesh或占据栅格。语义SLAM输出的是语义地图——在几何信息基础上加了物体类别、物体边界等信息。传统SLAM的地标是特征点,语义SLAM的地标可以是有语义含义的物体。语义SLAM的输出更适合机器人的高层任务规划和自然语言交互。

面试官:语义标注的准确率对SLAM有多大影响?

影响很大,但取决于语义信息在SLAM中的角色。如果只是做后处理标注(SLAM建图完了再贴语义),准确率影响的是最终地图的语义质量,不影响定位精度。如果语义信息参与了SLAM优化(比如物体级SLAM),标注错误会导致错误的数据关联,进而影响定位精度。所以语义信息参与优化时要加鲁棒核函数或者置信度权重。

面试官:语义SLAM有哪些开源方案?

视觉方面有SOS(Semantic ORB-SLAM)、Suma++、Kimera。激光方面有SuMa+、OverlapNet。Kimera做了一套完整的视觉惯性语义SLAM系统,开源代码质量不错。物体级SLAM方面CubeSLAM有开源代码。3D点云语义分割可以用MinkowskiEngine。

面试官:语义SLAM的实时性怎么样?

这是语义SLAM面临的主要挑战之一。语义分割网络(比如Mask R-CNN)推理一次要几十到几百毫秒,对于30fps的相机来说可能跟不上。解决方案:把语义分割放到独立线程,和SLAM主线程并行运行;降低语义处理的频率(比如每5帧做一次语义分割);用轻量级网络(比如MobileNet+DeepLab)。工程上独立线程+降频是最实用的方案。

面试官:语义SLAM在什么场景下最有价值?

服务机器人、家用机器人场景最有价值,需要理解环境语义才能执行高层任务。自动驾驶也需要——识别车道线、交通标志。仓储物流机器人需要识别货架和货物。需要机器人"理解环境"的场景,语义SLAM都有价值。


语义SLAM让机器人的地图从"几何信息"升级为"语义信息",是从"定位建图工具"到"环境理解系统"的关键一步。语义信息既帮助SLAM做得更准,又为机器人的高层决策提供了基础。

物体级SLAM是语义SLAM中最有前景的方向,把物体当作地标,输出对机器人最有用的语义地图。

上一篇:第261篇 多传感器融合SLAM——视觉+激光+IMU的组合方案 

下一篇我们聊深度学习在SLAM中的应用,看看learned features和端到端方案。

如果这篇文章对你有帮助,欢迎点赞支持一下,你的鼓励是我持续更新的动力!

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐