本文涉及的源码可从用二维图像渲染3D场景视频该文章下方附件获取
概述
NeRF(Neural Radiance Fields)是一种基于神经网络的3D场景表示技术。NeRF代表神经辐射场,它通过神经网络隐式地学习一个三维场景,从而能够根据观察者的位置和视角渲染出任意视角下的清晰照片。该技术最早在2020年ECCV会议的最佳论文中提出,自此迅速发展并应用于多个技术方向,如新视点合成和三维重建。然而,在不同分辨率的训练或测试图像观察场景内容时,NeRF的渲染过程可能会产生过度模糊或伪影的图像。对于传统NeRF来说,使用多条光线对每个像素进行超采样的渲染方案是不实际的,因为渲染每条光线需要对MLP进行数百次查询。
本文提出的mip-NeRF模型,将NeRF扩展到连续值尺度上。通过向像素点投射一个锥形区域(而非光线)进行采样,mip-NeRF减少了伪影的产生,显著提高了NeRF对细节的表示能力,同时比NeRF快7%,仅为NeRF的一半大小。与NeRF相比,mip-NeRF在NeRF呈现的数据集上的平均误差率降低了17%,在多尺度变体数据集上降低了60%。此外,mip-NeRF还拥有与超采样NeRF相当的准确性,而速度快22倍。
原理介绍
NeRF(Neural Radiance Fields)技术原理
NeRF使用一个多层感知机(MLP)神经网络去隐式地学习一个静态3D场景。这个网络接收一个5D向量(空间位置x, y, z,观察方向θ, φ)作为输入,并输出该空间点的颜色和密度。
通过体积渲染技术,将这些颜色和密度信息积累起来,从而生成任意视角下的图像。
NeRF使用一个连续的5D函数来表示场景,并使用少量的输入视图来优化这个函数以生成复杂场景的新视角。NeRF使用基于MLP的全连接神经网络来表示场景,输入为一个连续的5D坐标,包括空间位置(x,y,z)\和*观察视角(θ, φ),输出为该空间位置的体密度σ和与视角相关的RGB颜色*。通过沿着相机射线查询MLP并使用经典的体渲染技术将输出颜色和密度投影到图像中来生成新视图。
mip-NeRF模型技术原理
- 多尺度表示:mip-NeRF采用多尺度表示方法,能够实时表示连续尺度空间的预过滤辐射场。这种表示方法使得模型能够更好地处理不同分辨率和尺度的场景。
- 圆锥体采样:与NeRF使用单一光线进行采样不同,mip-NeRF使用圆锥体进行采样。这种方法有效地减少了混叠伪影,并显著提高了表现精细细节的能力。具体来说,mip-NeRF的输入是一个三维高斯,代表辐射场应被整合的区域,通过查询沿圆锥体的间隔来渲染一个预过滤的像素。
- 综合位置编码:为了对一个三维位置及其周围的高斯区域进行编码,mip-NeRF提出了一个新的特征表示:综合位置编码(IPE)。这是对NeRF的位置编码(PE)的概括,允许空间的一个区域被紧凑地特征化。
mip-NeRF的改进
- 使用圆锥追踪代替光线追踪,从而显著改善了抗锯齿(伪影)效果。
- 使用集成位置编码(IPE)特征代替传统的位置编码(PE)特征,实现了更高效的采样和尺度编码。
- 通过单一的多尺度模型(而不是NeRF中的每个尺度单独的模型),使得mip-NeRF的准确性、效率和简单性都得到了提高。
模型介绍
Mip-NeRF是一种用于解决神经辐射场(NeRF)中降采样和抗锯齿问题的改进模型,模型的处理过程如下:
- 对于场景中的每个像素,从相机的中心沿着像素中心的方向投射一个圆锥。
- 计算每个采样间隔的集成位置编码(IPE)特征,作为多层感知机(MLP)的输入。
- MLP输出密度和颜色,用于渲染场景。
环境配置/部署方式
安装环境
克隆项目源码
# 使用git克隆源码(笔者发现该源码由于作者更新过以后出现了些bug, # 笔者已经fork到自己的仓库,并修复了bug,推荐大家直接clone笔者的仓库) # git clone https://github.com/hjxwhy/mipnerf_pl.git #原作者仓库 git clone https://github.com/Ryan2ky/mipnerf_pl.git # 进入项目目录 cd mipnerf_pl
用conda创建虚拟环境
# 创建虚拟环境(推荐python版本为3.9.12) conda create --name mipnerf python=3.9.12 # 激活环境 conda activate mipnerf # 安装最新版的pip工具 conda install pip pip install --upgrade pip # 使用pip安装依赖库 pip install -r requirements.txt
注意:如果使用的linux环境不支持桌面GUI,请将
requirements.txt
中的opencv-python==4.5.4.58
依赖改为无头版本的opencv-python-headless==4.5.4.58
安装pytorch依赖
可以前往Start Locally | PyTorch根据自己的操作系统环境选择合适的pytorch版本:
注意:pytorch的cuda工具包版本应根据显卡所支持的cuda版本选择(可使用nvidia-smi
命令查看)
(一般应满足:[pytorch+cuda]版本 <= [Cuda]版本)
执行安装命令:
pip3 install torch torchvision torchaudio
准备数据
在项目根目录中创建一个
data
目录用来存放训练数据我们使用谷歌官方的NeRF数据集(下载链接见附件
README.md
中的Dataset小节)进行实验,将nerf_synthetic.zip
下载并解压到data
目录下将
nerf_synthetic
数据集转换成多尺寸mipmap数据集python datasets/convert_blender_data.py --blender_dir ./data/nerf_synthetic --out_dir ./data/multiscale
至此,我们拥有了2个数据集,结构如下:
- data
- nerf_synthetic(单一尺寸Blender数据集)
- multiscale(多尺寸Blender数据集)
训练(train)
我们以lego这一数据集为例,进行单尺寸和多尺寸的训练:
配置
我们可以在
configs
文件夹下配置训练的参数,默认使用的是configs/default.yaml
,其中已经配置好了lego场景的参数,我们可以复制一份到lego-multiscale.yaml
,并修改exp_name
为lego_multiscale
加以区分。读者还可以根据需求配置一些其他的参数,例如:check_interval
:验证并保存模型的频率,该参数表示每经过一定步数,即进行一次验证,并保存模型到ckpt文件夹下。resume_path
:从ckpt恢复模型以继续训练,首次训练时应当设为None
表示无需从ckpt恢复。
训练
# 训练单一尺寸数据集 python train.py --out_dir ./out --data_path ./data/nerf_synthetic/lego --dataset_name blender # 训练多尺寸数据集 python train.py --out_dir ./out --data_path ./data/multiscale/lego --dataset_name multi_blender --config ./config/lego-multiscale.yaml
中断与恢复
默认配置下,训练会不断进行(不超过
max_steps
),当认为差不多时,可以手动ctrl+c
终止训练。训练模型保存在./out/{exp_name}/ckpt
中。如果因为异常导致终止,我们也可以从之前保存的ckpt中恢复,只需在配置文件中指定
resume_path
为具体的ckpt文件即可。
评估(eval)
#单尺寸模型评估
python eval.py --ckpt ./out/lego/ckpt/last.ckpt --data ./data/nerf_synthetic/lego --out_dir ./out --scale 1 --save_image
#多尺寸模型评估
python eval.py --ckpt ./out/lego_multiscale/ckpt/last.ckpt --data ./data/multiscale/lego --out_dir ./out --scale 4 --save_image
评估结果存放在./out/{exp_name}/test
下。
渲染(render)
# 单尺寸模型渲染
python render_video.py --ckpt ./out/lego/ckpt/last.ckpt --out_dir ./out --scale 1
# 多尺寸模型渲染
python render_video.py --ckpt ./out/lego_multiscale/ckpt/last.ckpt --out_dir ./out --scale 4
渲染结果保存在./out/{exp_name}/render_spheric
下。
小结
mip-NeRF在3D渲染、虚拟现实、增强现实等领域具有广泛的应用前景。其能够合成逼真场景和模型的能力使得它在游戏制作、影视特效以及仿真培训等方面具有巨大的潜力。随着技术的不断发展,mip-NeRF有望在未来发挥更大的作用。