0%

使用instant-ngp生成NeRF模型

项目官网:Instant Neural Graphics Primitives with a Multiresolution Hash Encoding

项目Repo:NVlabs/instant-ngp

Paper:Instant Neural Graphics Primitives with a Multiresolution Hash Encoding

按照官网的介绍,instant-ngp可以用在四个领域:

  • Neural gigapixel images
  • Neural SDF
  • NeRF
  • Neural volume

这篇博文主要介绍其中NeRF的使用方法。

实际上官方的READMETips都很全面,可以作为先行参考。

准备

直接使用Releases

项目官方已经提供了构建好的,为Windows平台准备的Releases,可以在NVlabs/instant-ngp - Releases中找到。

分别是:

自己构建

如果使用Linux,或者想用Python binding,或者Releases中没有你所使用的GPU,那么可以自己来构建instant-ngp项目

因为我没有Linux下构建过此项目,因此这里省略Linux的部分,需要的可以直接去看官方README

环境要求

  • 一块NVIDIA GPU;如果拥有Tensor Core可以提高性能。官方Repo所有显示的结果均来自RTX 3090;
  • 支持 C++14 的编译器。官方推荐并测试了以下选择:
    • Windows: Visual Studio 2019或2022;
    • Linux: GCC/G++ 8或更高。
  • 最新版本的CUDA。官方推荐并测试了以下选项:
    • Windows: CUDA 11.5或更高;
    • Linux: CUDA 10.2或更高;
  • CMake v3.21或更高;
  • 【可选的】Python 3.7或更高用于交互binding。记得运行pip install -r requirements.txt
  • 【可选的】OptiX 7.6或更高版本用于更快的网格SDF训练;
  • 【可选的】用于支持启用DLSS的Vulkan SDK

构建

克隆instant-ngp的Repo,并进入目录:

1
2
git clone --recursive https://github.com/nvlabs/instant-ngp
cd instant-ngp

在instant-ngp目录下,使用cmake构建项目:

1
2
cmake . -B build
cmake --build build --config RelWithDebInfo -j

Windows平台需要使用Visual Studio的developer command prompt

训练前准备

相机位置数据

NVlabs的instant-ngp的NeRF部分与原始NeRF代码兼容,都是使用transforms.json记录初始相机参数。

但是考虑到大多数人的设备可能只有一个摄像机/手机摄像头,因此NVlabs提供了一个脚本:scripts/colmap2nerf.py,使用开源项目COLMAP来处理视频文件或图像序列,来生成项目必要的相机位置数据。

除此之外,还可以使用基于ARKit的Record3D来获取相机数据,但这要求你有一台iPhone 12以上的iPhone。根据NVlabs的说法,对于缺少纹理或包含重复内容的场景,使用Record3D要比COLMAP更加强大。

然而可惜我并没有iPhone,因此这部分并不会写到本博文。如有需要,参考:Record3D

模型对训练数据的挑剔

训练过程对数据集是有一定要求的:

  • 数据集必须有良好的覆盖范围,即重建的主体必须有足够的数据覆盖;
  • 不包含错误的相机位置数据以及模糊的帧(运动模糊和散焦模糊),这些都会对结果造成致命性的影响;

NVlabs官方的一个经验,如果你的模型在20秒左右仍然未收敛,那么经过更长时间之后它也不太可能变得更好。因此,官方建议在训练的早期阶段调整数据以获得更清晰的结果。
对于更大的真实场景,多训练的结果只能获得一丁点的清晰度。几乎所有的收敛都发生在最初的几秒钟内。

其他注意事项

  • 数据集常见的问题是相机位置的比例或偏移不正确。
  • 如果图像太少,或者相机位置数据不正确(例如COLMAP未能生成位置结果)。在这种情况下,一般需要更多的图像,或者调整计算相机位置的过程。这超除了instant-ngp项目本身实现的范围。

数据集准备

现有数据集

如果你之前就已经有了NeRF的数据集,那么instant-ngp可以与之兼容。只需要做出一些小小的修改。

关于这一点,请参考:Existing Datasets

准备新的NeRF数据集

要训练自己的数据集,必须将数据处理成instant-ngp支持的格式。NVlabs提供了三种方式:

  • COLMAP:从您拍摄的一组照片或视频创建数据集
  • Record3D:使用iPhone 12 Pro或更新版本(基于 ARKit)创建数据集
  • NeRFCapture:使用iOS设备创建数据集或将摆姿势的图像直接传输到instant-ngp。

在这里我只介绍不需要iPhone即可使用的COLMAP,如果你需要了解另外两种方式,请参考:Record3DNeRFCapture

这三种方法都要求Python 3.7或更高版本,并加入到了环境变量PATH中。

使用COLMAP将视频或图片转换为instant-ngp支持的数据集

对于Linux系统,需要先行安装COLMAP和FFmpeg。

对于Windows系统,则在运行脚本的同时会自动安装所有需要的依赖。

如果输入的文件是视频,可以使用以下包含NVlabs推荐参数的指令来运行scripts/colmap2nerf.py

1
data-folder$ python [path-to-instant-ngp]/scripts/colmap2nerf.py --video_in <filename of video> --video_fps 2 --run_colmap --aabb_scale 32

以上假定单个视频文件作为输入,FFmpeg会以指定的帧速率(此处为2)提取帧。

NVlabs建议选择可以产生大约50~150张图像的帧速率,对于一分钟的视频来说,--video_fps 2是理想的选择。

如果输入的文件是图像,要先将他们放到名为images的子文件夹中,然后使用以下包含NVlabs推荐参数的指令来运行scripts/colmap2nerf.py

1
data-folder$ python [path-to-instant-ngp]/scripts/colmap2nerf.py --colmap_matcher exhaustive --run_colmap --aabb_scale 32

scripts/colmap2nerf.py这个脚本将根据需要运行FFmpeg和COLMAP,并将结果转换为transforms.json的格式,然后写入当前目录。

默认情况下,该脚本使用 sequential matcher 调用COLMAP,这适用于 平滑变化 的相机路径拍摄的图像。

如果视频/图像没有特定排序,则使用 exhaustive matcher 更为合适。

对于更多选项,可以使用--help运行脚本。

有关COLMAP更高的使用,或者具有挑战性的场景,需要参阅COLMAP的文档,这可能需要修改scripts/colmap2nerf.py脚本本身。

aabb_scale参数是 最重要 的instant-ngp参数。该参数指定场景的范围,默认值为1——寄,场景缩放使得相机位置与原点的平均距离为1个单位。

对于原始NeRF数据集等小型合成场景,默认的--addbb-scale 1是理想的选择,可以实现更快的训练。对于背景超出此边界框的自然场景,NeRF模型将会难以处理并产生一些“漂浮物”。

通过将aabb-scale设置为更大的2的次方(最大为128),NeRF模型会将光线扩展到更大的边界框。

请注意:这回稍微影响训练速度。对于自然场景,从128aabb_scale开始,随后逐渐减少它。顺便一提,这个值可以直接在transforms.json输出文件中编辑,无需重新运行scripts/colmap2nerf.py脚本。

您可以选择传入运行Detectron2以自动生成掩码的对象类别(例如--mask_categories person car)。 instant-ngp不会使用屏蔽像素进行训练。此实用程序对希望忽略移动或敏感物体(例如人、汽车或自行车)的用户很有帮助。有关类别列表,请参阅scripts/category2id.json

NeRF

在instant-ngp的目录下运行:

1
instant-ngp$ ./instant-ngp [path to training data folder containing transforms.json]