简介:一份围绕 NeRF-SLAM 复现过程整理的中文技术文档,面向已具备视觉 SLAM 基础、希望将神经辐射场引入稠密建图的研究生与算法工程师。内容从传统 ORB-SLAM 稀疏关键点的局限切入,依次拆解 Tracking 阶段的 Instant-NGP 深度监督、RAFT 光流估计与 Droid SLAM 协方差建模,重点说明 DBA 层如何借助舒尔补和 Cholesky 分解求解相机位姿与路标点逆深度;Mapping 部分讨论概率体素化 NeRF、哈希编码加速以及平衡深度与颜色监督的 Mapping Loss,并对比噪声深度、无纹理区域下的收敛表现。压缩包仅含 1 个 docx,约 11.01MB,可作为论文阅读后的对照笔记与复现路线索引。已有 2327 人学习,文档还记录了环境安装、数据集下载和运行环节的踩坑与解决思路,便于读者少走弯路。
1. 复现 nerf-slam 的准备工作:先看清这套环境的版本要求
拿到这份 nerf-slam 复现文档时,我做的第一件事是把机器上那套旧环境整个清掉。原因很直接:它固定使用 CUDA 11.3 加 torch 1.12.1,而我上半年为了跑别的模型已经把 CUDA 升到 12 系、torch 换成了 2.x。这类三维重建复现项目最反直觉的地方在于,代码本身没多复杂,安装失败几乎全发生在版本对上——cmake 差一个小版本,instant-ngp 就编不过;Boost 少一个 serialization,gtsam 的 python wrapper 就直接生成不出来。它适合手上有一张能跑 CUDA 11.3 显卡、想从连续单目 RGB 图像直接得到稠密重建结果的人,也适合已经踩过 nice-slam 那类需要额外深度输入的同学。下面按我实际安装的顺序写,从环境清点一路写到第一帧结果怎么确认。
2. 环境清单与版本锁定:CUDA 11.3、torch 1.12.1 与 cmake 3.22 的对应关系
装环境最容易犯的错误是“先装再说”,结果装到一半发现某个库要求 cmake 3.22 以上,回头重编要连带清掉一堆编译缓存。我的习惯是先把版本一次性列成表,逐条用命令验证过再动手。这套 nerf-slam 的依赖链其实不深,但横跨 Python、C++、CUDA 三块,任何一块版本不对,最后都是同一个报错:编译中断。
2.1 显卡驱动与 CUDA 运行时的区别
很多人看到nvidia-smi右上角写着 CUDA Version 12.x,就以为系统里装的是 CUDA 12,然后纠结要不要降级。这里要分清两件事:nvidia-smi显示的是驱动能支持的最高运行时版本,属于上限;nvcc --version显示的才是真正装在本机的 CUDA Toolkit 版本。torch 1.12.1+cu113 那个 wheel 包里自带 CUDA 运行时,所以你系统里没装 CUDA 11.3 的 Toolkit,import torch一样能跑通、一样能上显卡。
# 驱动能力上限,看右上角那一行 nvidia-smi # 系统里实际安装的 CUDA Toolkit,没装过会提示 command not found nvcc --version只有一种情况必须装 Toolkit:后面要编译自定义 CUDA 算子。这份复现流程里 instant-ngp 和 gtsam 都是纯 C++/CUDA 编译,走的是 cmake 那一套,系统里有完整 Toolkit 会更省事。我一般会装一个 CUDA 11.3 的 Toolkit 并在环境变量里指过去,避免 nvcc 找不到。
| 组件 | 锁定值 | 校验命令 | 不对时的典型表现 |
|---|---|---|---|
| 显卡驱动 | 能支持 CUDA 11.3 即可 | nvidia-smi | import torch报 driver 版本过低 |
| CUDA Toolkit | 11.3 | nvcc --version | 编译 ngp 时报 nvcc 不匹配 |
| Python | 3.8 / 3.9 | python -V | 装 torch 1.12.1 时找不到 wheel |
| PyTorch | 1.12.1+cu113 | torch.__version__ | 与文档不一致,后续 API 报错 |
| torchvision | 0.13.1+cu113 | torchvision.__version__ | 与 torch 版本错配,import 失败 |
| cmake | 大于 3.22 | cmake --version | 配置 instant-ngp 直接不通过 |
| GLEW | 系统包 | dpkg -l libglew-dev | Could NOT find GLEW |
| Boost | 1.73.0 | ls /usr/local/lib/libboost* | Could NOT find Boost (missing: ...) |
2.2 编译器与系统库的底线
原文只提了 cmake 要大于 3.22,没写编译器,但这块经常出问题。CUDA 11.3 的 nvcc 对 GCC 版本有硬性白名单,GCC 11 及以上会直接抛unsupported GNU version,常见做法是把 GCC 降到 9 或 10,用update-alternatives切过去。我一般会先确认一下当前默认版本,再决定要不要切:
gcc --version g++ --version # Debian 系装机必备的底层依赖,缺了后面 cmake 会一个接一个报错 sudo apt update sudo apt install -y build-essential git wget curl unzip \ libglew-dev libglfw3-dev libfreeimage-dev libxi-dev libxinerama-dev libxcursor-dev这里提前把libglew-dev装掉,是因为后面编译 instant-ngp 时Could NOT find GLEW (missing: GLEW_INCLUDE_DIRS GLEW_LIBRARIES)这个报错出现的概率极高,几乎每个人都会遇到一次。与其等到编译中断再回头装,不如现在一次性补全。
2.3 虚拟环境与目录规划
Python 侧的依赖必须隔离。torch 1.12.1 这个版本已经比较老,装在系统 Python 里会和别的项目打架,出问题还原起来非常麻烦。我一般用 venv,比 conda 轻,也不会引入另一套 CUDA 运行时干扰判断:
# 建议放在空间充足的盘上,编译产物不小 mkdir -p ~/work && cd ~/work python3.9 -m venv .venv source .venv/bin/activate # 老版本 pip 解析 +cu113 这种本地版本号会失败,必须先升级 python -m pip install --upgrade pip setuptools wheel升级 pip 这一步别省。torch 1.12.1+cu113 的版本号带本地标识,pip 版本太旧时解析--extra-index-url里的索引会找不到匹配项,报No matching distribution found,新手很容易误判成网络问题去反复重试。
目录规划上我习惯把编译产物和源码分开,因为 cmake 的缓存一旦写脏,重来最省事的办法就是删掉整个 build 目录重建:
# 最终目录大概长这样,build_ngp / build_gtsam 都是独立产物目录 # ~/work/ # .venv/ Python 虚拟环境 # nerf-slam/ 主仓库,thirdparty 下有两个子模块 # build_ngp/ instant-ngp 编译目录 # build_gtsam/ gtsam 编译目录 # data/ 数据集,单独放,别塞进仓库提示:源码目录和数据目录一定要分开。三维重建的数据集体积大,混在仓库里,
git status会一直提示有变更,排查问题时干扰很大。
3. 拉代码与装 Python 依赖:submodule、torch 和两份 requirements
这一章的三个步骤有严格顺序:先带子模块克隆,再装 torch,最后装两份 requirements。顺序打乱会出问题:如果先装 requirements,它可能会把已经装好的 torch 降级或替换成别的版本,前面那步就白做了。
3.1 子模块必须一起拉下来
这个仓库把 instant-ngp 和 gtsam 都做成了 submodule,放在thirdparty/下。直接下载 zip 包或者用--depth 1浅克隆,目录会是空的,后面 cmake 配置时找不到./thirdparty/instant-ngp这个路径,报错信息还很不直观。
# 仓库地址用项目文档里给的那条,不要用第三方镜像 git clone <repo-url> --recurse-submodules cd nerf-slam # clone 时带了 --recurse-submodules 也要再跑一次, # 因为嵌套子模块不会在首次 clone 时全部拉完 git submodule update --init --recursive这两条命令都要执行。--recurse-submodules只对首次 clone 生效,而且只拉一层;git submodule update --init --recursive是幂等的,多跑一次没坏处,能把嵌套依赖补齐。拉完之后用下面这条确认,每个子模块前面都应该是提交哈希,前面带减号说明没初始化成功:
git submodule status # 正常输出形如: 3f2a1c... thirdparty/instant-ngp (heads/main) # 如果行首是 -,说明该子模块还没拉下来3.2 装 torch 1.12.1+cu113
原文给的命令是固定版本,别改成pip install torch,装出来大概率是 2.x,后面代码里用的接口对不上。这里用的是--extra-index-url而不是--index-url,区别很关键:前者是“额外再查这个源”,主源还能用;后者是“只用这个源”,会导致后面装 requirements 里其他包时全部去 PyTorch 源里找,找不到就报错。
# CUDA 11.3 对应的 wheel,版本号必须带 +cu113 后缀 pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 \ --extra-index-url https://download.pytorch.org/whl/cu113装完立刻验证,别急着往下走。下面这条一次性打出三个值:torch 版本、编译时的 CUDA 版本、显卡是否真的可用。第三个是False的话,后面所有重建都会在初始化阶段挂掉,而且报错位置很深,不好排查。
python -c "import torch; print(torch.__version__, torch.version.cuda, torch.cuda.is_available())" # 期望输出:1.12.1+cu113 11.3 True如果torch.version.cuda是None,说明装成了 CPU 版,原因是没带+cu113后缀,或者 pip 从主源里挑了一个同名的 CPU 包。这种情况不用犹豫,pip uninstall torch torchvision卸干净重装。
3.3 两份 requirements 的安装
仓库里有前后两份依赖清单:根目录下一份,gtsam 子模块里还有一份,后者是 python wrapper 需要的东西。原文的顺序是先根目录后 gtsam,我按这个来,因为 gtsam 那份里有些包依赖根目录已经装好的版本。
# 第一份:主仓库依赖 pip install -r requirements.txt # 第二份:gtsam python wrapper 的依赖,路径是相对仓库根目录的 pip install -r ./thirdparty/gtsam/python/requirements.txt第二条命令里的路径容易写错。./thirdparty/gtsam/python/requirements.txt是相对路径,必须在仓库根目录下执行;如果你已经cd到别处,就会报No such file or directory。这不是依赖缺失,是路径问题,别被误导。
装完之后做一次整体自检,把可能出问题的 import 一次性过一遍,比等到跑流程时报错强得多:
python - <<'EOF' import torch, torchvision print("torch", torch.__version__, "cuda ok:", torch.cuda.is_available()) # 这几个是重建流程里常用到的数值和图像库,缺一个后面都会中断 import numpy, scipy, cv2, yaml print("numpy", numpy.__version__, "cv2", cv2.__version__) EOFcv2那个 import 名字和包名不一样,装的是opencv-python,导入的是cv2,这一点新手经常弄混,看到ModuleNotFoundError: cv2会去pip install cv2,装上一个完全不相干的包。
3.4 Python 版本对 gtsam wrapper 的影响
gtsam 的 python wrapper 是用 pybind11 编译出来的,编出来的.so和编译时的 Python 版本绑定。如果系统里有多个 Python,cmake阶段找到的是 3.8,而你在 3.9 的虚拟环境里 import,就会报ModuleNotFoundError或者符号未定义。
常见做法是在 cmake 之前显式指定解释器路径,把虚拟环境里的那个传进去:
# 在仓库根目录执行,确保 cmake 用的是虚拟环境里的 Python which python # 输出应该是 ~/work/.venv/bin/python记住这个路径,下一章编译 gtsam 时会用到。如果which python输出的是/usr/bin/python3,说明虚拟环境没激活,或者激活后又被别的 shell 配置覆盖了,先解决这个再继续。
4. 编译两个第三方库:instant-ngp 与 gtsam 的完整依赖链
Python 侧搞定只是前半程,真正耗时间的是这两个 C++ 库。instant-ngp 负责哈希编码加速的 NeRF 渲染,gtsam 负责位姿图优化和 DBA 那部分的求解,两个都得编。这一章按“先升 cmake、再编 ngp、补 Boost、最后编 gtsam”的顺序走,中间任何一步失败都别跳过。
4.1 cmake 升级到 3.22 以上的三条路径
文档里明确写了cmake>3.22,但系统自带的往往是 3.16 或 3.18,直接配置会在cmake_minimum_required那一行退出。原文里记了三条升级路径,我按适用场景整理成表,选择哪条取决于你的发行版包管理是否够新:
| 方式 | 版本 | 是否需要编译 | 适用场景 |
|---|---|---|---|
| 官方二进制包 | 3.22.0-rc2 | 否,解压即用 | 想快速验证,能接受 rc 版本 |
| 源码编译 | 3.9.2 | 是,./configure那套 | 老系统,需要兼容旧项目 |
| 源码编译 | 3.26.3 | 是,./configure那套 | 长期使用,版本稳定 |
我最后停在 3.26.3。3.22.0-rc2 虽然是二进制包、解压就能用,但版本号里带rc,个别 CMakeLists 里做版本字符串比较时会出问题,不值得为省十分钟冒这个险。二进制包这条路可以留着应急:
# 二进制包,解压后把 bin 目录加进 PATH 即可 wget <cmake 官网 files 目录>/v3.22/cmake-3.22.0-rc2-linux-x86_64.tar.gz --no-check-certificate tar -zxvf cmake-3.22.0-rc2-linux-x86_64.tar.gz export PATH=$PWD/cmake-3.22.0-rc2-linux-x86_64/bin:$PATH--no-check-certificate是原文就带的参数,某些环境里证书链不完整会导致 wget 直接失败,加上这个能绕过。源码编译那条路以 3.26.3 为例,步骤是标准的 configure 流程:
tar -xvf cmake-3.26.3.tar.gz cd cmake-3.26.3/ # --prefix 不指定就装到 /usr/local,我一般保持默认 ./configure sudo make -j$(nproc) && sudo make install编完之后有一件事必须做:刷新 shell 的命令路径缓存。hash -r清掉旧的 cmake 路径记录,否则cmake --version还会显示老版本,你会以为装失败了。
hash -r cmake --version # 必须显示 3.26.3 才继续往下走 which cmake # 确认指向 /usr/local/bin/cmake注意:
hash -r之后如果版本还是旧的,说明/usr/local/bin在 PATH 里排在/usr/bin后面,或者系统里装了多个 cmake。用which -a cmake全部列出来,再调整 PATH 顺序。
4.2 编译 instant-ngp 与 GLEW 缺失的处理
instant-ngp 的编译目录我单独放成build_ngp,和主仓库的构建分开,这样出问题删掉重建不影响别的。配置命令用的是-B指定构建目录,这条命令必须在仓库根目录执行,因为路径参数是相对的:
cd ~/work/nerf-slam cmake ./thirdparty/instant-ngp -B build_ngp第一次跑大概率会撞上 GLEW 报错,原文里记录得很清楚:Could NOT find GLEW (missing: GLEW_INCLUDE_DIRS GLEW_LIBRARIES)。这个库是 OpenGL 的扩展加载器,做实时渲染预览要用到。解决方式就一行:
sudo apt install libglew-dev # 装完重新配置,cmake 会重新走一遍查找流程 cmake ./thirdparty/instant-ngp -B build_ngp装完包之后一定要重新执行一次 cmake 配置,而不是直接--build。因为 find_package 的结果会被缓存进CMakeCache.txt,不重新配置的话它还会用缓存里“没找到”的结论继续报错,反复几次都是同一个错,很容易让人误以为包装错了。
配置通过后开始编译,原文指定的构建类型是RelWithDebInfo,带优化又保留调试符号,比纯Release更适合排查数值问题,代价是编译慢一点、产物大一点:
# -j 后面不跟数字就是无限并行,容易吃满内存, # 内存小的机器建议写成 -j4 或 -j8 cmake --build build_ngp --config RelWithDebInfo -j这一步耗时最长,视机器而定。编译中途如果出现internal compiler error或者被 OOM Killer 杀掉,基本都是并行度太高,降到-j4重来。编完之后看一下产物目录,正常情况下应该有可执行文件和 Python 扩展模块:
ls -lh build_ngp/ # 关注两个东西:一个可执行程序,一个 pyngp 的 .so 扩展模块 # 没有 .so 说明 python 绑定没编,后面的脚本会 import 失败4.3 源码编译 Boost 1.73 解决 gtsam 依赖
gtsam 依赖 Boost 的一堆组件,原文报错列得很全:serialization system filesystem thread program_options date_time timer chrono regex,要求至少 1.65。系统包管理器装出来的版本经常不够,或者拆包拆得太碎,缺组件。源码编译最稳妥,以 1.73.0 为例:
# 从 Boost 官方发布页拿 1.73.0 的源码包 wget <boost 发布地址>/boost_1_73_0.tar.bz2 --no-check-certificate tar xvf boost_1_73_0.tar.bz2 cd boost_1_73_0 # 生成 b2 构建工具,它会自动探测本机的编译器和 Python ./bootstrap.sh # --buildtype=complete 表示连静态库一起编,install 装到默认前缀 sudo ./b2 --buildtype=complete install--buildtype=complete的意思是完整构建,不省略静态库。原文作者提到为了省事选了完全安装,我认同这个取舍:Boost 的组件依赖关系比较绕,只挑需要的几个编,后面很容易在链接阶段发现少了某个间接依赖,再回头重编一次,时间成本更高。
安装路径默认是/usr/local,最终所有libboost*都会落在/usr/local/lib下。装完要跑一次ldconfig让动态链接器认识新库,否则 gtsam 配置阶段能过、编译链接阶段会报找不到符号:
# 刷新动态链接库缓存,没这一步 gtsam 链接会失败 sudo ldconfig # 抽查几个关键组件是否都在 ls /usr/local/lib/libboost_serialization* /usr/local/lib/libboost_system*如果要指定路径,编译时加--prefix=xxx,但装完必须手动把该路径加进LD_LIBRARY_PATH和CMAKE_PREFIX_PATH,否则 cmake 找不到。我一开始图省事用了自定义前缀,结果 gtsam 配置时死活找不到 Boost,折腾了半小时才想起环境变量没配,这是典型的先给自己制造问题。系统里有多个 Python 版本时,还可以用--with-python=python3.9指定,默认走系统默认版本,这一步和 3.4 节讲的是同一个问题。
4.4 打开 GTSAM_BUILD_PYTHON 编译 python wrapper
Boost 装好之后回到仓库根目录,重新配置 gtsam。-DGTSAM_BUILD_PYTHON=1这个开关不能漏,它决定要不要生成 Python 绑定,漏了的话后面import gtsam一定失败,而编译过程本身一点错都不报,属于比较隐蔽的一个问题:
cd ~/work/nerf-slam cmake ./thirdparty/gtsam -DGTSAM_BUILD_PYTHON=1 -B build_gtsam配置成功的话,输出里会出现 Python 相关的几行,包括找到的解释器路径和 pybind11 的状态。如果这里显示的解释器是系统 Python 而不是虚拟环境里的,八成是虚拟环境没激活,重新激活后删掉build_gtsam再配一次,缓存的解释器路径不会自动更新。
# 构建类型和 ngp 保持一致,方便统一排查 cmake --build build_gtsam --config RelWithDebInfo -j$(nproc)编完之后需要把 wrapper 装进当前虚拟环境,常见做法是在构建目录里跑 python 安装目标,具体目标名以 gtsam 的 CMakeLists 为准:
# 进构建目录找 python 相关的目标 cmake --build build_gtsam --target help | grep -i python # 常见做法是下面这条,装到当前激活的虚拟环境 cd build_gtsam && sudo make python-install && cd ..装完验证一下,这条命令能打出 gtsam 版本号就说明 wrapper 真的可用,而不只是编出来了:
python -c "import gtsam; print(gtsam.__version__)"5. 排查与避坑:复现 nerf-slam 时最容易出问题的五处
前面四章是“顺利路径”,实际装的时候大概率会在下面这几处卡住。我把它们按现象、原因、解决拆开写,对照着看能省不少时间。
5.1 子模块目录是空的
现象:cmake ./thirdparty/instant-ngp -B build_ngp报路径不存在,或者ls thirdparty/instant-ngp什么都没有。
原因:克隆时没用--recurse-submodules,或者用了但只拉了第一层,嵌套子模块仍然是空的。用 zip 包下载的情况更彻底,.gitmodules里记录的地址根本没被处理。
解决:在仓库根目录补跑git submodule update --init --recursive,然后git submodule status逐行检查,行首有减号的就是没拉下来的。如果某个子模块地址已经失效,删掉对应目录重新 init,别在残留目录上硬修。
5.2 cmake 版本显示对不上
现象:明明装完了新 cmake,cmake --version还是老的;或者sudo cmake --version是新的,普通用户执行是旧的。
原因:一是 shell 的命令路径缓存没刷;二是/usr/local/bin和/usr/bin的 PATH 顺序问题;三是sudo走的是secure_path,和当前用户的 PATH 不是一套。
解决:先hash -r,再which -a cmake把所有实例列出来,确认/usr/local/bin在前。前面 4.1 节特意留了这一步,就是踩过。
5.3 Boost 装了但 gtsam 还是找不到
现象:Boost 1.73.0 显示安装成功,/usr/local/lib下也能看到libboost*,重新 cmake gtsam 还是报Could NOT find Boost。
原因:自定义了--prefix但没配CMAKE_PREFIX_PATH,或者装完没跑ldconfig。还有一种是只装了头文件没装库,b2 install没带--buildtype=complete时可能跳过部分库。
解决:先用ls /usr/local/lib/libboost_serialization*确认库文件真实存在,再sudo ldconfig,然后在 cmake 命令里显式加-DBOOST_ROOT=/usr/local。三步都做过还不行,就删掉build_gtsam整个重建,缓存里的查找结果不会自动刷新。
5.4 编译到一半进程被杀
现象:cmake --build跑到某个[ 45%]之后进程突然消失,没有报错,或者只有一行Killed。
原因:并行度太高,每个编译单元又都是重模板的 CUDA 代码,内存瞬间打满,被系统 OOM Killer 干掉。8G 内存的机器用-j无限并行基本必挂。
解决:把并行度压到-j4甚至-j2,加 swap 也能缓解。观察free -h在编译过程中的内存曲线,峰值超过物理内存就说明并行度还是高了。这种“没报错的失败”最消耗耐心,知道是内存问题能省很多排查时间。
5.5 python wrapper 编了但 import 失败
现象:build_gtsam目录下能看到.so文件,import gtsam还是报ModuleNotFoundError或者undefined symbol。
原因:编出来的.so绑定的 Python 版本和当前虚拟环境不一致,或者装到了系统 site-packages 而不是虚拟环境里。sudo make python-install这种写法很容易装错位置,sudo会切换到 root 的环境。
解决:先python -c "import sys; print(sys.prefix)"确认当前解释器位置,再用pip show gtsam看装到哪了。位置不对就卸掉重装,安装命令别加sudo,让 pip 自己决定路径。
6. 验证跑通:从空环境到第一帧稠密重建结果的检查清单
装完不等于跑通。三维重建这类项目最麻烦的地方是,即使环境全对,也可能因为数据路径、图像格式、内参文件的问题,跑出一个颜色正常但几何完全错位的结果。我习惯在正式跑长序列之前,先用短序列做一次端到端验证,把问题拦在早期。
第一步是数据准备。按仓库 README 里 Download Datasets 那一节来,通常是连续的单目 RGB 图像序列,配合时间戳和相机内参文件。目录结构别自己发挥,按它给的布局放:
# 目录结构按 README 给的来,图像序列、时间戳、内参三样缺一不可 ls ~/work/data/<序列名>/ # 检查项:图像数量和时间戳行数是否一致 ls ~/work/data/<序列名>/images/ | wc -l wc -l ~/work/data/<序列名>/timestamps.txt这两个数字对不上,跑起来会在某一帧突然中断,或者位姿估计整体漂移。我在一个序列上就栽过,图像比时间戳多两帧,前面几百帧都正常,到末尾直接崩,日志里还看不出原因。
第二步是运行入口。仓库根目录下的脚本名不同分支可能不一样,先看清楚再执行:
cd ~/work/nerf-slam source ~/work/.venv/bin/activate # 先看看根目录有哪些可执行入口 ls *.py *.sh 2>/dev/null # 按 README 的 Run 一节传参数,配置文件和序列路径一般都要显式指定第三步判断结果对不对,这一步比前面都重要。跑起来不报错不代表结果正确,下面三个判据是我每次都会看的:
| 判据 | 正常表现 | 异常表现与对应原因 |
|---|---|---|
| 跟踪阶段位姿输出 | 相邻帧位姿连续变化 | 位姿跳变,多为内参或时间戳错位 |
| 深度图 | 结构边缘清晰、无大片噪声 | 深度全灰或全黑,检查协方差权重是否生效 |
| 渲染结果 | 颜色与输入图像一致 | 颜色偏移,多为坐标系或颜色通道顺序问题 |
看日志的时候重点关注跟踪阶段的重投影误差和深度损失两项,它们如果从第一帧开始就居高不下,说明输入数据本身有问题,别继续浪费时间等收敛,先回去查数据。这套方法在无纹理区域尤其明显:传统方法在那里基本没有关键点可用,而 NeRF 这条路线靠体渲染的连续性还能恢复出结构,前提是深度监督的权重设置正确。
第四步做一个小的消融对照。同一个短序列,一次用完整流程跑,一次关掉深度监督只靠颜色,对比两者的重建稠密度。正常情况下前者明显更完整,如果差别不大,说明深度那条链路根本没起作用,可能是协方差文件没读到,也可能是权重参数被默认值覆盖了。
从那以后我每次复现这类 NeRF-SLAM 项目,都会先用一个十帧左右的短序列把整条链路跑一遍,确认跟踪、深度、渲染三个环节都出结果,再切到长序列。这个习惯帮我省掉了好几次“跑了四小时才发现数据路径写错一个字母”的返工。希望帮到你。
本文还有配套的精品资源,点击获取