使用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的使用方法。
准备
直接使用Releases
项目官方已经提供了构建好的,为Windows平台准备的Releases,可以在NVlabs/instant-ngp - Releases中找到。
分别是:
- RTX 3000 和 4000 系列、RTX A4000–A6000 以及其他 Ampere 和 Ada 卡;
- RTX 2000 系列、Titan RTX、Quadro RTX 4000–8000 和其他 Turing 卡
- GTX 1000 系列、Titan Xp、Quadro P1000–P6000 和其他 Pascal 卡
自己构建
如果使用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,并进入目录:
git clone --recursive https://github.com/nvlabs/instant-ngp
cd instant-ngp
在instant-ngp目录下,使用cmake构建项目:
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,如果你需要了解另外两种方式,请参考:Record3D和NeRFCapture。
这三种方法都要求Python 3.7或更高版本,并加入到了环境变量PATH中。
使用COLMAP将视频或图片转换为instant-ngp支持的数据集
对于Linux系统,需要先行安装COLMAP和FFmpeg。
对于Windows系统,则在运行脚本的同时会自动安装所有需要的依赖。
如果输入的文件是视频,可以使用以下包含NVlabs推荐参数的指令来运行scripts/colmap2nerf.py
:
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
:
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模型会将光线扩展到更大的边界框。
请注意:这回稍微影响训练速度。对于自然场景,从
128
的aabb_scale
开始,随后逐渐减少它。顺便一提,这个值可以直接在transforms.json
输出文件中编辑,无需重新运行scripts/colmap2nerf.py
脚本。
您可以选择传入运行Detectron2
以自动生成掩码的对象类别(例如--mask_categories person car
)。 instant-ngp不会使用屏蔽像素进行训练。此实用程序对希望忽略移动或敏感物体(例如人、汽车或自行车)的用户很有帮助。有关类别列表,请参阅scripts/category2id.json
。
NeRF
在instant-ngp的目录下运行:
instant-ngp$ ./instant-ngp [path to training data folder containing transforms.json]