NeRF,全名为 Neural Radiance Fields,是一种基于深度学习的三维场景隐式表示和渲染方法
NeRF的核心思想是通过神经网络训练出来的辐射场对场景进行隐式表示。这种表示方式与传统的使用体素、网格或点云的显式表示不同,NeRF将整个场景看作一个连续的函数,即Radiance Fields
F ( x , d ) = ( σ , c ) F(\bf x, d) = (\sigma, c) F(x,d)=(σ,c)
这个函数接受三维空间坐标 x \bf x x 和观察方向 d \bf d d 作为输入,输出相应位置的颜色 c \bf c c 和体密度 σ \sigma σ
经过上面,得到空间中任意点的体积密度和定向发射辐射度。使用经典体渲染的原理来渲染穿过场景的任何光线的颜色
从连续神经辐射场渲染视图需要估计通过所需虚拟相机的每个像素追踪的相机光线的积分 C ( r ) C(r) C(r)
由于 ( x , y , z ) (x,y,z) (x,y,z) 方向向量只有三维,如果直接将其喂给神经网络,那神经网络也只能返回低维的信息,信息不足导致模糊。所以位置编码即把输入拓展成更高维,那输出的就会包含更高维的信息
使用的编码函数是:
ϕ ( x ) = ( sin ( 2 0 π x ) , cos ( 2 0 π x ) , … , sin ( 2 d − 1 π x ) , cos ( 2 d − 1 π x ) ) . \phi(\mathbf{x}) = (\sin(2^0 \pi x), \cos(2^0 \pi x), \ldots, \sin(2^{d-1} \pi x), \cos(2^{d-1} \pi x)). ϕ(x)=(sin(20πx),cos(20πx),…,sin(2d−1πx),cos(2d−1πx)).
实验中,我们设置 d = 10 d=10 d=10 用于位置坐标 ϕ ( x ) ϕ(\bf x) ϕ(x) ,所以输入是60维的向量; d = 4 d=4 d=4 用于相机位姿 ϕ ( d ) ϕ(\bf d) ϕ(d) 对应的则是24维
均匀在光线上采样会有存在点位浪费、欠采样的问题(稀疏的地方采样多了,稠密的地方采样少了),所以针对某些粒子浓稠区域(表示遇到实体了),信息量大,需要重点采样
同时优化两个网络:一个粗网络和一个精网络
这样一来,神经网络便可以在信息量大的区域获得更有效,更正确的信息
NeRF使用神经网络,一个多层感知机(MLP),来近似这个Radiance Fields函数
在训练阶段,NeRF使用已知场景的图像和相机参数作为输入,通过最小化生成图像与真实图像之间的差异来优化神经网络的参数。
大致过程:
随机射线采样:在每次优化迭代中,从数据集的所有像素中随机采样一个相机射线批次
分层采样:从粗网络查询 N c N_c Nc 个样本和从精网络查询 N f = N c + N r N_f = N_c + N_r Nf=Nc+Nr 个样本
体积渲染:应用体积渲染过程,使用从粗网络和精网络获得的样本渲染每个射线的颜色
损失计算:
损失函数( L \mathcal{L} L )定义为粗渲染和精渲染的渲染像素颜色和真实像素颜色之间的总平方误差:
L = ∑ r ∈ R ∥ C ^ c ( r ) − C ( r ) ∥ 2 2 + ∥ C ^ f ( r ) − C ( r ) ∥ 2 2 \mathcal{L} = \sum_{\mathbf{r} \in \mathcal{R}} \left\| \hat{C}^c(\mathbf{r}) - C(\mathbf{r}) \right\|_2^2 + \left\| \hat{C}^f(\mathbf{r}) - C(\mathbf{r}) \right\|_2^2 L=r∈R∑ C^c(r)−C(r) 22+ C^f(r)−C(r) 22
其中 R \mathcal{R} R 表示每个批次中的射线集, C ( r ) C(\mathbf{r}) C(r) 是真实颜色, C ^ c ( r ) \hat{C}^c(\mathbf{r}) C^c(r) 是粗网络预测的颜色, C ^ f ( r ) \hat{C}^f(\mathbf{r}) C^f(r) 是精网络预测的颜色