1. 算法介绍
- 核心思想
NeRF 的基本思想是用神经网络作为一个 3D 场景的隐式表达,代替传统的点云、网格、体素、TSDF 等方式,同时通过这样的网络可以直接渲染任意角度任意位置的投影图像。
训练时使用对一个场景拍摄的多张图片,将场景信息存储在神经网络的参数中。
1)提出一种用 5D 神经辐射场 (Neural Radiance Field) 来表达复杂的几何+材质连续场景的方法,该辐射场使用 MLP 网络进行参数化;
2)提出一种基于经典体素渲染 (Volume Rendering) 改进的可微渲染方法,能够通过可微渲染得到 RGB 图像,并将此作为优化的目标。该部分包含采用分层采样的加速策略,来将 MLP 的容量分配到可见的内容区域;
3)提出一种位置编码 (Position Encoding) 方法将每个 5D 坐标映射到更高维的空间,这样使得我们可以让我们优化神经辐射场更好地表达高频细节内容。
- 场景表示和渲染
- 场景表示:表示场景中物体位置、材质,环境光等信息的数学表示,一般有以下几种表示方式:
a. 体素(Voxel):模拟仿真
b. 网格(Mesh):游戏,电影
c. 点云(Point Cloud):激光雷达数据
d. 隐式表示:SDF(Signed Distance Function
- 渲染:使用场景的3D表示信息生成2D的逐像素颜色
a. 光栅化(rasterization)
b. 光线追踪(ray tracing)
c. 光线步进(ray marching)
- 神经辐射场表示场景
使用一个5D函数作为场景的隐式表示,输入为(x, y, z, theta, phi),输出为(r, g, b, sigma)。
输入xyz表示某一可见点在空间中的位置,(theta,phi)表示相机视角,若输入不包括相机视角,则无法实现高光 (specular) 的效果。
输出rgb表示该点的颜色,sigma为volume density,可以看成是透射系数。
使用下图所示MLP网络表示映射函数
- 基于辐射场的体积渲染
从相机发射一条光线 r(t) = o + td,near平面t = tn,far平面t = tf
光线对应的颜色可表示为
t的离散化处理:将tn - tf区间均匀分成成N段,从每个小段中均匀采样一个t值。
上式对ci和sigmai都是可微的,所以可以通过使用神经网络的输出结果渲染成图像,计算结果与实际图像之差来优化神经网络的参数。
- 训练神经辐射场
a. 位置编码(Positional Encoding)
网络的输入(x,y,z,theta,phi)均为低频信息,难以使用神经网络表示场景的高频信息。
将输入映射到高维空间中,便于网络学习高频信息。
将(x, y, z, theta, phi)中的每个分量都从一维映射到2L维。对位置 L = 10,对视角 L = 4。
b. 分层体积采样(Hierarchical Volume Sampling)
场景空间中的很多位置不包含物体,或者是被遮挡的,这些部分对体积渲染不产生贡献,简单的均匀采样会产生大量的冗余计算。
作者训练coarse和fine两个网络,两个网络分别将tn - tf区间分成Nc段和Nf段。Nc < Nf。
首先使用coarse网络,对Nc个分段进行采样并训练,获得整个区间上volume的分布。再使用fine网络根据分布进行采样,在物体密集的地方多采样,稀疏的地方少采样。
c. 训练
训练使用同一场景拍摄的多张图片,以及相机内参,外参和场景范围。
若是合成图像或者拍摄没有记录相机参数,则使用COLMAP sfm包计算参数。
每次迭代是随机选取一个batch的光线,通过神经网络输出光线上对应点的color,sigma,通过体积渲染获得光线对应的输出颜色,计算输出颜色与光线实际颜色之差作为loss函数。