
传统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(fcam_{t}) # 物体位姿节点 for obj in detected_objects: graph.add_pose_node(fobj_{obj.id}) # 观测因子相机观测到了某个物体 for obs in observations: graph.add_factor(fcam_{obs.frame}, fobj_{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, keylambda x: x[1]) if candidates else None面试追问环节面试官语义SLAM和传统SLAM的区别是什么传统SLAM输出的是几何地图——点云、mesh或占据栅格。语义SLAM输出的是语义地图——在几何信息基础上加了物体类别、物体边界等信息。传统SLAM的地标是特征点语义SLAM的地标可以是有语义含义的物体。语义SLAM的输出更适合机器人的高层任务规划和自然语言交互。面试官语义标注的准确率对SLAM有多大影响影响很大但取决于语义信息在SLAM中的角色。如果只是做后处理标注SLAM建图完了再贴语义准确率影响的是最终地图的语义质量不影响定位精度。如果语义信息参与了SLAM优化比如物体级SLAM标注错误会导致错误的数据关联进而影响定位精度。所以语义信息参与优化时要加鲁棒核函数或者置信度权重。面试官语义SLAM有哪些开源方案视觉方面有SOSSemantic ORB-SLAM、Suma、Kimera。激光方面有SuMa、OverlapNet。Kimera做了一套完整的视觉惯性语义SLAM系统开源代码质量不错。物体级SLAM方面CubeSLAM有开源代码。3D点云语义分割可以用MinkowskiEngine。面试官语义SLAM的实时性怎么样这是语义SLAM面临的主要挑战之一。语义分割网络比如Mask R-CNN推理一次要几十到几百毫秒对于30fps的相机来说可能跟不上。解决方案把语义分割放到独立线程和SLAM主线程并行运行降低语义处理的频率比如每5帧做一次语义分割用轻量级网络比如MobileNetDeepLab。工程上独立线程降频是最实用的方案。面试官语义SLAM在什么场景下最有价值服务机器人、家用机器人场景最有价值需要理解环境语义才能执行高层任务。自动驾驶也需要——识别车道线、交通标志。仓储物流机器人需要识别货架和货物。需要机器人理解环境的场景语义SLAM都有价值。语义SLAM让机器人的地图从几何信息升级为语义信息是从定位建图工具到环境理解系统的关键一步。语义信息既帮助SLAM做得更准又为机器人的高层决策提供了基础。物体级SLAM是语义SLAM中最有前景的方向把物体当作地标输出对机器人最有用的语义地图。上一篇第261篇 多传感器融合SLAM——视觉激光IMU的组合方案下一篇我们聊深度学习在SLAM中的应用看看learned features和端到端方案。如果这篇文章对你有帮助欢迎点赞支持一下你的鼓励是我持续更新的动力