☰
ORB-SLAM2语义标注实战:从环境配置到三维点云标签生成全流程
2026/10/14 4:41:12 网站建设 项目流程

1. 项目概述:说清楚这套东西能干吗

先交代一下背景。这个项目叫“完整跑出orb_slam2 with labelling记录”,单看标题就知道两件事:第一是把经典的ORB-SLAM2从头到尾跑通,第二是在这个基础上加了labelling,也就是给SLAM过程中生成的地图点、关键帧或者轨迹打上语义标签。这两件事叠在一起,就成了一个非常典型的“视觉SLAM+语义信息”的复现项目。

先说为什么要折腾这么一套东西。ORB-SLAM2本身是一个开源的视觉SLAM系统,支持单目、双目和RGB-D三种传感器模式,核心功能就是实时估计相机位姿、构建稀疏点云地图。它有多经典呢?到现在为止,做视觉SLAM的人几乎都拿它当过基线系统。但“跑通”和“跑好”是两回事。很多人下载源码、编译、跑数据集,结果发现不是版本冲突就是跑出来的地图不对,更别提在此基础上加labelling了。

labelling这个需求通常来自更高层的任务。比如机器人拿到一张地图,光有几何结构还不够,它还得知道哪些点是桌子、哪些点是椅子、哪些区域是墙壁,这样才能做语义导航、场景理解或者人机交互。换句话说,labelling给纯几何的SLAM地图补上了“这个东西是什么”的维度。

这个项目适合谁?三类人最适合参考这篇记录:

  • 刚接触视觉SLAM、想用ORB-SLAM2做基础复现的研究生或者工程师;
  • 已经跑通纯SLAM、但需要往地图里塞语义信息的人;
  • 以及那些被环境配置折磨到快放弃、就想看看别人怎么一步步排雷的实操党。

我前后折腾这个项目大概用了五六天时间,中间踩了不少坑,有些坑在网上根本搜不到直接的解决方案,只能靠反复试。这篇文章就是把整个流程完完整整拆开来讲,包括依赖版本怎么选、CMakeLists要改哪几处、标签模型怎么接进来、跑数据集时哪些参数必须动,以及我实际遇到的报错和排查方法。

2. 整体设计拆解:为什么这么搭配,到底解决什么问题

2.1 “SLAM+labelling”这个组合背后的逻辑

纯ORB-SLAM2输出的是一堆三维点,每个点只有一个位置坐标和描述子,你根本不知道它对应的是桌子腿还是墙上的插座。而labelling要做的事情,就是给这些点赋予一个语义类别。

在动手之前,我建议你先想清楚一个问题:标签是加在哪个环节?

这个问题的答案决定了整个技术路线。大致上有两种做法,我分别说下优劣:

第一种:在后端对地图点做离线语义标注。具体做法是跑完SLAM、拿到点云地图之后,用一个语义分割网络对关键帧图像做逐像素分类,然后把像素类别反投影到三维点上。优点是实现简单,不用改SLAM前端的代码,缺点是标签是“事后”贴上去的,只有那些能被关键帧图像覆盖到的点才有标签,而且累计误差会导致投影位置有偏移。

第二种:在SLAM线程里实时融合语义信息。也就是在跟踪线程或者局部建图线程里,把每一帧的语义分割结果和当前地图关联起来,逐帧更新点的标签。这种做法的实时性和一致性更好,但实现复杂度明显上升,你得维护好帧到点、点到标签之间的索引关系。

我这次项目采用的是“第一种为主,第二种为辅”的混合策略:跑ORB-SLAM2得到地图和关键帧位姿,再用语义分割模型给关键帧打标签,最后通过投影把标签传回地图点。整体链路清晰,每一步都可以单独验证,对初学者来说友好得多。

2.2 整体技术链路与技术选型理由

整个系统的数据流向是这样的:

  • ORB-SLAM2跑TUM或者KITTI数据集,输出相机轨迹和稀疏点云;
  • 从关键帧中抽取图像,送入语义分割模型得到逐像素类别图;
  • 利用关键帧的位姿、相机内参以及深度信息(RGB-D模式下),将像素类别映射到三维空间;
  • 根据每个地图点在多帧中的类别投票结果,决定最终标签;
  • 最后把带标签的点云导出,用可视化工具逐帧复盘。

这么走有几个好处。第一,每一环都是独立模块,哪里出了问题可以单独排查,不用在一团乱麻里找bug。第二,复用已有的成熟工具:ORB-SLAM2本身不用大改,语义模型选一个对显存要求不高的轻量级网络就行。第三,整个链路不依赖ROS,纯命令行就能跑通,大大降低了环境复杂度。

我用的工具清单如下:

  • Ubuntu 20.04系统;
  • ORB-SLAM2源码(需要针对依赖版本做小幅修改);
  • Eigen 3.3.7、OpenCV 4.5.4、Pangolin 0.6;
  • 一个轻量级语义分割模型,输出13类常见室内物体类别;
  • 一段自写的标签投影脚本,负责建立关键帧像素与地图点的映射关系。

这套组合选型的核心原则就一条:尽量用稳定版本,不追新。比如Pangolin 0.6和OpenCV 4.x的组合是经过大量人验证过的,换成新版本反而容易出现API不兼容的问题。

3. 实操全流程解析:从环境准备到跑出带标签地图

3.1 环境准备与依赖安装:版本搭配是第一道坎

我强烈建议,如果你不是对版本很有把握,不要用太新的系统。ORB-SLAM2的源码本身就有些年头了,很多早期代码对C++11、OpenCV 3.x/4.x、Pangolin 0.5/0.6有依赖,Ubuntu 20.04是一个比较舒服的中间版本,既不会太老导致编译器缺失,也不会太新导致兼容性翻车。

依赖安装顺序有讲究,不要一上来就装OpenCV。我的顺序是:

  • 先更新系统软件源,装build-essential、cmake、git这些基础工具;
  • 安装Eigen,直接用apt装3.3.7,版本太高需要改代码里的头文件路径;
  • 安装OpenCV 4.5.4,使用源码编译安装,这一步耗时最长,实测大概需要20到30分钟;
  • 安装Pangolin 0.6,注意要先装它的依赖库,否则编译会报缺少头文件的错;
  • 最后装ORB-SLAM2所需的其余依赖,包括DBoW2、g2o等,这些在源码自带的Thirdparty目录里可以一并编译。

有个非常容易踩的坑:很多人在编译Pangolin时遇到“Could NOT find GLEW”或者“No package 'GL' found”这类报错。原因就是系统缺少OpenGL相关的开发包。解决办法也很直接,安装libglew-dev、libglu1-mesa-dev、libegl1-mesa-dev这几个包,然后再编译就好。

我记录一下实际的依赖安装命令,方便参考:

sudo apt update sudo apt install build-essential cmake git pkg-config # Eigen sudo apt install libeigen3-dev # OpenCV依赖 sudo apt install libgtk2.0-dev libgtk-3-dev libavcodec-dev libavformat-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev # Pangolin依赖 sudo apt install libglew-dev libglu1-mesa-dev libegl1-mesa-dev libwayland-dev libxkbcommon-dev wayland-protocols # 编译OpenCV 4.5.4(源码放在家目录下) cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D WITH_CUDA=OFF \ -D BUILD_opencv_python3=ON .. make -j8 sudo make install

OpenCV编译时建议把CUDA关掉,除非你真的需要在GPU上跑图像处理。关掉之后编译速度会快不少,而且对ORB-SLAM2这种场景来说CPU版本完全够用。

3.2 ORB-SLAM2源码获取与编译配置

源码获取不细说了,直接clone下来就行。拿到源码后,第一步别急着编译,先看一下CMakeLists.txt,这里面藏了不少默认路径假设,不改的话编译大概率会报错。

我在修改CMakeLists时主要动了三处:

第一处,是OpenCV的版本指定。因为之前装的是OpenCV 4.5.4,但有些版本的ORB-SLAM2源码里写的是OpenCV 3.x的find_package写法,如果不改就会报找不到OpenCV的错误。需要把find_package(OpenCV 3.4 REQUIRED)改成find_package(OpenCV REQUIRED),让CMake自己去找合适的版本。

第二处,是设置Pangolin的路径。如果你是通过apt或者默认方式安装的Pangolin,一般不会有大问题。但如果源码是从别处拷贝来的,在Ubuntu 20.04上常见的一个错误是找不到libPangolin.so,需要在CMakeLists里显式设置Pangolin_DIR变量。

第三处,是给编译加一个“忽略不兼容弃用警告”的选项。因为C++的编译器越来越严格,老代码里有些写法在新标准下会变成warning甚至error,比较典型的是std::bind的用法变化,还有reinterpret_cast相关的类型转换。最省事的做法是在每个模块的CMakeLists里加上:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-deprecated -Wno-deprecated-declarations")

当然更讲究的做法是逐行修正源码,但时间有限的话,这个方案性价比最高。

整个编译过程分两步。第一步是编译Thirdparty里的DBoW2和g2o,第二步才是编译ORB-SLAM2主程序。如果你用的是源码自带的build.sh脚本,它会自动按顺序执行。实测整个编译过程大概需要10到15分钟,取决于机器性能。

编译完成的标志是有几个可执行文件生成:单目是mono_tum、mono_kitti,双目是stereo_kitti,RGB-D是rgbd_tum。看到这些文件出现,就说明基础系统已经跑通了。

3.3 数据集准备与yaml参数调整:为什么必须改这几个参数

ORB-SLAM2跑数据集之前,需要两个输入:一个是yaml配置文件,里面写了相机内参、畸变系数、ORB特征提取参数等,另一个是数据集本身。

我这次用的是TUM RGB-D数据集,选的是办公室场景序列。TUM数据集的格式很标准,包含RGB图序列、深度图序列,以及groundtruth轨迹文件。下载之后,把RGB图和深度图分别放到两个文件夹里,再准备一个association.txt文件做时间戳对齐,这是ORB-SLAM2读取数据时依赖的文件格式。

写一个简单的脚本把RGB图和深度图关联起来,这一步很容易出错。TUM数据集的rgb.txt和depth.txt时间戳可能不完全一致,需要用最近邻匹配。我当时写了一个几十行的Python脚本来处理,核心逻辑是:对每一行的RGB时间戳,在深度图时间戳列表里找到最接近的一个,如果时间差小于某个阈值(比如0.02秒),就认为这是一对有效帧。

yaml文件的修改也是一门学问。TUM数据集的真实参数可以从数据集官网上查得到,拿来直接用就行。但有几个参数我建议必须根据自己的目标调整:

  • ORBextractor.nFeatures,提取ORB特征点的数量,默认1000个。如果你跑的是低纹理场景,可以适当提高到1500,让特征点更密集;
  • ORBextractor.nScaleLevels,金字塔层数,默认8层。这个参数影响尺度的连续性,对深度变化大的场景,可以提高到10;
  • ThDepth,深度阈值,在RGB-D模式下很关键。它决定了多少范围外的点被视为“远景”,过小会导致远处的地图点缺失;
  • RGBD.bCreateMap,是否创建八叉树地图。如果你的下游任务不需要稠密地图,可以保持默认,但如果你想做labelling的可视化,建议关掉它,用稀疏点云配合标签就够看了。

这里有个实操经验:yaml改完参数后,不用重新编译,直接改配置文件就行,这一点非常方便调试。你可以在跑不同数据集时准备多份yaml,切换时直接指定不同文件。

3.4 跑通单目/RGB-D模式的实际输出什么

跑单目模式时,终端会输出跟踪线程的状态信息,并弹出一个Pangolin窗口实时显示当前帧的特征点、关键帧和地图点。跑完后,终端会统计平均跟踪时间、关键帧数量和地图点数量。

跑RGB-D模式时,界面类似,但多了深度图的参与。因为每帧都带深度信息,所以建图效果比单目好很多,地图点的尺度也是真实的。我当时跑了大约1700帧的数据,最后得到的地图点数量大概在8万到10万之间,平均跟踪时间在20到30毫秒每帧,表现还算稳定。

有一点需要说明:默认的ORB-SLAM2输出的是稀疏点云地图,只有特征点对应的三维点,不是稠密重建。如果你想在后面做labelling时看到“有实际物体形状”的稠密点云,就得额外处理。我这次是保持稀疏点云,因为在“给地图点打标签”这个需求下,稀疏点云正好够用。

4. 标签模型接入与投影原理:核心环节详解

4.1 选哪个语义分割模型,跑哪些类别

Labelling的核心是把图像像素分类成语义类别,然后再把类别传给地图点。语义分割模型我试了两种,一种是大模型,效果好但推理速度太慢,跑一帧要几百毫秒,完全跟不上SLAM的实时性,只适合事后离线处理。另一种是小模型,速度快但类别少,精度也弱一些。最后我选择了后者,因为SLAM地图上的标签不要求像素级的精细边界,只要类别大致准确就行。

我实际用的模型输出类别包括:背景、墙壁、地板、天花板、桌子、椅子、显示器、门、书架、杂物等13类,覆盖了办公室场景里的主要结构物和物体。这个粒度对于导航和交互任务来说已经够用了。

模型输入分辨率默认是512×320,对一幅标准TUM图像来说会先做缩放。这带来一个问题:像素坐标的变化会影响投影精度,所以你必须记住模型推理时用的尺寸和原图尺寸之间的换算关系,否则标签对齐会出偏差。

4.2 像素标签到三维点的投影计算

这一步是整个labelling的枢纽。逻辑不复杂:对于ORB-SLAM2中的某个地图点,它会被多个关键帧观测到。在每一帧观测中,这个三维点通过相机内外参可以投影到图像像素坐标,然后查这个像素的语义类别,就能知道在这一帧里它被看成什么物体。多帧综合投票,得票最多的类别就是它的最终标签。

公式核心是:

[ X_c, Y_c, Z_c ]^T = R * [ X_w, Y_w, Z_w ]^T + t x = f_x * X_c / Z_c + c_x y = f_y * Y_c / Z_c + c_y

其中R和t是这一帧相机的旋转和平移,也就是ORB-SLAM2输出的位姿;f_x、f_y、c_x、c_y是相机内参,在yaml文件里。计算出来的(x, y)就是像素坐标,四舍五入后直接去查语义分割图里对应位置的类别。

这里需要注意一个细节:ORB-SLAM2的帧对象里有mvKeys,也就是这一帧提取到的特征点。每个地图点会记录哪些帧观测到它,以及对应的特征点索引。所以投影时最稳妥的做法不是用“地图点坐标自己投影到像素”,而是直接用帧里已经匹配好的特征点的像素坐标,这样能减少一次投影误差。

我写标签投影脚本时的流程大概是这样:

  • 解析ORB-SLAM2保存的帧位姿文件,或者直接从运行时内存中拿到位姿数据;
  • 遍历ORB-SLAM2生成的MapPoint文件,读取每个点的世界坐标、观测帧ID和特征点索引;
  • 对每个观测帧,拿到该帧图像,用训练好的模型推理出逐像素类别图;
  • 把特征点像素坐标映射到模型输入尺寸对应的坐标,查类别;
  • 收集一个地图点在所有观测帧中的类别投票,最终确定标签;
  • 输出带标签的点云文件,格式可以自己定义,比如每一行代表x y z label。

整个过程听起来顺畅,但实际操作中会碰到几个问题。最典型的是重复计算:多个地图点可能被同一个帧观测到,如果每个点都独立推理一次图像,效率极低。我的做法是先对所有关键帧做一次批量推理,将语义分割结果保存成数组,后续查询直接在内存里查表就行,速度提升非常明显。

其次,深度缺失问题。RGB-D数据集中,深度图在某些区域可能没有有效值,这会导致地图点在投影时缺少Z坐标,没法做三角化。对于这些点,我会检查它们的观测帧数量,如果太少就直接丢弃,因为标签的可信度也不高。

4.3 可视化验证的三种手段

跑完labelling之后,必须做可视化验证,否则你无法确认标签到底准不准。我推荐三种验证手段:

第一种,看彩色点云。在点云可视化工具中给每一个标签类别赋予一个固定颜色,桌子的点全部是红色、椅子的点全部是蓝色、墙是灰色。一眼扫过去就能看出有没有错乱。我排查时发现过一种典型问题:某一块墙上的点被标成了“书架”,因为关键帧里这个位置刚好被书架遮挡,而这个点又在书架的边缘。这种错乱在视觉上很直观,能快速定位是哪一步出了问题。

第二种,叠加到原图上。把某个关键帧的语义分割图半透明叠加在RGB图上,检查模型分割结果本身有没有大的区域错误。比如有些亮度极低的暗部区域,模型容易把它识别成背景,但实际是椅子的一部分;这种情况下就算投影逻辑正确,标签也是错的,需要从模型侧改进。

第三种,轨迹上逐帧回放。这是最能发现系统性问题的手段。拉一条相机轨迹,在轨迹的各个位姿处渲染对应的点云标签,边走边看。如果某个区域的标签在相邻几帧之间频繁变化,极有可能是投票策略的问题,比如投票帧数太少导致分类不稳定。我会在脚本里加入一个“最少投票帧数”的阈值,低于这个阈值的点直接标为未知类别,不参与后续统计。

5. 完整流程的参数选择与代码实现要点

5.1 标签投票策略怎么定

在多帧投票阶段,有几个参数直接决定标签质量。我实测下来比较可靠的参数组合是:

  • 最少投票帧数设为3,即一个地图点至少有3帧观测支持,才给它一个确定标签;
  • 票数阈值设为最高票占总票数的50%以上,换句话说,如果3帧里是“墙、墙、门”,那么“墙”以2票胜出,OK;如果是“墙、门、门”,2票“门”胜出,也算OK;但如果是“墙、门、显示器”各一票,那就没法决出明确类别,只能标为“不确定”;
  • 置信度阈值设为0.7,模型预测某一类别的softmax概率低于这个值的像素,直接置为“背景”,不参与投票。

这几条规则看起来简单,但能有效过滤掉大量噪声标签。举个例子,一个桌角在某一帧中被模型识别成了“杂物”,但另外四帧都被识别成了“桌子”,最终投票结果“桌子”4票胜出,这个点就是稳定可靠的地图标签。

如果你用的模型输出的是logits而不是概率,需要先加softmax计算概率,再用上面的置信度阈值处理。

5.2 点云文件与标签文件的导出格式

导出格式可以根据下游任务的需要自定义,但我建议采用一种通用、开放、方便别的工具读取的格式。我用的格式是每一行:

x y z r g b label_name

其中x y z是三维坐标,r g b是颜色值(可以把label对应的颜色也写进去,方便渲染),label_name是类别名。用约定分隔符隔开,比如逗号或空格。

另外建议同时导出一个带位姿信息的文本文件,格式为:

frame_index tx ty tz qx qy qz qw

这样后续做语义地图、训练下游模型或者调试时,可以随时把点云和轨迹对齐,不需要重新跑SLAM。

我碰到过一个问题:导出后某些点在可视化工具里显示位置异常,检查发现是点云文件中混入了NaN坐标。原因是部分地图点在ORB-SLAM2的优化阶段没有被更新,坐标一直保持初始值。解决办法是在导出脚本里增加一个简单的滤除逻辑:

if not all(map(lambda v: v == v, [x, y, z])): continue

顺手把这个逻辑也应用到标签置信度低的点,坐标有效但标签不可靠的点,可以在导出时标记成“unknown”,别让它们影响后续统计。

5.3 代码结构如何组织更省心

这个项目里我自己写了不少胶水代码,为了让逻辑清晰,我把它分成了几个独立模块:

  • 数据关联模块:负责读ORB-SLAM2输出和数据集,做帧与位姿的时间戳对齐;
  • 语义分割推理模块:封装模型的加载与前向推理,输出类别图;
  • 标签投影模块:实现像素到三维点的映射和投票策略;
  • 可视化模块:生成带颜色点云和轨迹文件。

这种模块化设计的好处是,如果后面想换一个更强的分割模型,只需要替换推理模块,投影逻辑不用动。如果想把标签从稀疏点云扩展到稠密点云,只需要在投影模块里加入新的稠密点生成逻辑,也基本不干扰其他部分。

项目跑通之后,我最大的感受是:代码写得多不如写得顺,清晰的数据流和模块边界,能帮你省下大量排查错误的精力。

6. 常见问题与排查技巧实录:那些网上很难搜到的坑

6.1 编译期的三类高频报错与对策

我整理了一下实际项目中高频出现的编译期报错,这些在复现ORB-SLAM2类项目时几乎人人都会碰到。

第一类是Pangolin找不到OpenGL相关库。报错表现是CMake配置阶段提示“Could NOT find OpenGL”或者编译阶段提示“GL/gl.h no such file”。原因很简单:没有安装OpenGL的开发头文件。对策是装齐libgl1-mesa-dev和libglew-dev。如果你的系统是Ubuntu 22.04或更高版本,还需要装libegl1-mesa-dev和libwayland-dev,因为新版Pangolin默认启用EGL和Wayland支持,缺了就编译不过。

第二类是OpenCV版本不匹配。如果你系统里原来就装着一个OpenCV 3.x,又手动编译了一个OpenCV 4.x,CMake可能会找到旧版本,导致头文件可用但库文件对不上。最有效的排查方法是先彻底卸载旧的OpenCV,再统一安装新版本。如果不想卸载,就需要在CMakeLists里用set(OpenCV_DIR)显式指定新版本路径。

第三类是编译器标准问题。老代码常见一个编译错误,提示“use of deleted function”或者“call to implicitly-deleted copy constructor”。这是因为旧代码里的某些类在新C++标准下不允许默认拷贝。这种问题最省事的规避方法是在编译命令里加-fno-copy-elision,但根本解决办法是找到出问题的类定义,给它补充拷贝构造函数。如果只是做课程复现,前者就够用了。

6.2 运行期的诡异问题与排查日志

编译过了不代表万事大吉,运行期会遇到更考验耐心的怪问题。

我遇到的一个典型问题是:跑TUM数据集时,前几百帧跟踪正常,但突然跟踪丢失,程序退出。查了很多资料后发现,根因多半在ORB-SLAM2的Local Mapping线程里出现了坏帧。解决方法有两个方向:第一是调整yaml里的特征点数量,把它提高,让特征分布更均匀;第二是检查数据集的帧率,如果帧率太高或者图像分辨率太大,可以隔帧采样或者缩小图像尺寸。

另一个问题是:地图点明明跑出来了,但数量少得可怜,只有几千个。这个现象多数是ORBextractor的nFeatures设得太低,或者图像的纹理太弱。我后来把nFeatures从1000提高到2000,地图点数量立刻翻倍,效果立竿见影。

标签投影时最常见的怪问题,是“标签永远对不上”。场景中的桌子和椅子的点被标成了墙。排查了几轮后发现,问题出在图像缩放上:语义模型输入是512×320,但投影时直接用原始图像坐标查表,坐标差了整整一倍。修正方法很简单,先按照缩放比例把像素坐标换算过去,再做类别查询。

还有一个比较隐藏的坑:多帧投票时,如果直接把所有观测帧的像素类别都记下来,不检查这个点在这一帧是否真的可见,会出现“点在墙后面却被标成桌子”的错误。因为地图点在当前帧的投影位置可能落在遮挡物上。解决办法是加一个最简单的一致性检查:在投影到像素后,比较地图点的深度和该像素在深度图上的实际深度,如果两者差得远,说明被遮挡了,要丢弃这一帧的投票。

6.3 问题速查表

我把常见问题整理成一张速查表,方便排查时快速定位:

问题现象可能原因处理办法
编译Pangolin报缺GL/GLEW缺OpenGL开发包装libgl1-mesa-dev libglew-dev
跑数据集时跟踪频繁丢失特征点太少 / 帧率太高提高nFeatures,隔帧采样
地图点数量很少nFeatures过低 / 纹理弱提高nFeatures,调低金字塔层数
标签整体偏移缩放/坐标换算错误检查模型输入尺寸与原图比例
部分标签闪烁不稳定投票帧数不够增加最少投票帧数阈值
点云中出现NaN坐标地图点未更新导出时过滤NaN

7. 实操总结:我最想提醒你的一件事

整个项目跑完之后,我复盘时最大的感触是:这套流程里每一步都不是纯技术问题,更多是理解数据流与位姿关系的“工程直觉”。如果你只是照着教程把命令跑完,那你得到的只是一堆点云文件;只有当你真正理解了“像素类别如何通过关键帧位姿回到三维点”这条链路,你才能在没有现成解决方案的场景里自己定位问题。

基于这次经验,给你三个实操建议:

第一,不要一开始就追求“离线高精度标注”,先把完整链路跑通,得到一个哪怕粗糙的带标签地图。粗糙版本的价值在于帮你验证所有模块之间的连接是否正确。之后再逐步提升分割模型的精度、增加投票策略的复杂度。

第二,参数调整要有意识地做单变量控制。一次只改一个参数,跑一次数据,记一次结果。我最初图省事一次改了好几个参数,结果地图点数量变化了,但根本不知道是哪个参数起的作用,白白浪费了半天时间。

第三,把“处理遮挡”当作必须考虑的需求,而不是可选项。语义标注最稳定的点,往往是大平面上的点,比如墙壁、地面;最容易出错的,恰恰是物体边缘和遮挡交界处。如果你未来的应用涉及动态场景或者多物体交互,遮挡处理会占据你调参的一半精力。

这个项目做完后,我已经把标签导出格式和投影脚本封装好,后续想再接一个稠密重建模块,将稀疏点云升级成有语义标签的稠密八叉树地图。到时候再跑一轮数据,看看稠密点云的标签效果和投影误差会不会有惊喜。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询