原创自:
https://zhuanlan.zhihu.com/p/642737320
简介
NeRF(Neural Radiance Fields)最早在2020年ECCV会议上发表。之后,NeRF迅速发展起来,被应用到多个技术方向上例如新视点合成、三维重建等等,并取得非常好的效果。将隐式表达推上了一个新的高度。
近年来相关工作集合:https://github.com/awesome-NeRF/awesome-NeRF
原始NeRF论文:NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis
代码:GitHub - bmild/nerf: Code release for NeRF (Neural Radiance Fields 原始代码是基于TensorFlow,后面不久就有了Pytorch版本
工作流程:
NERF用 2D 的 posed images 作为监督,无需对图像进行卷积,而是通过不断学习位置编码,用图像颜色作为监督,来学习一组隐式参数,表示复杂的三维场景。通过隐式表示,可以完成任意视角的渲染。
算法框架
将沿相机光线查询的5D 坐标作为网络输入,输出颜色和密度。使用经典的体积渲染技术将体积和密度投影到图像中。由于体积渲染是自然可微分的,因此整个过程可训练,优化所需的唯一输入是一组具有已知相机姿势的图像。
通过限制网络仅将体积密度σ预测为位置x的函数,同时允许将RGB颜色c预测为位置和观看方向的函数,来鼓励表示为多视角一致。为了实现这一点,MLP Fθ首先处理具有8个完全连接层的输入3D坐标x(使用ReLU激活和每层256个通道),并输出σ和256维特征向量。然后,该特征向量与相机光线的观看方向连接,并传递到一个额外的完全连接层(使用ReLU激活和128个通道),该层输出依赖于视图的RGB颜色
这种方法能够不同位置的颜色变化,以及同一位置不同方向的颜色变化。下图在船舶场景的神经表示中可视化了两个空间位置的示例方向颜色分布。在下图(a)和(b)中,展示了来自两个不同相机位置的两个固定3D点的外观:一个在船侧(橙色插图),另一个在水面(蓝色插图)。NERF能够预测这两个3D点不断变化的规范外观,(c)中展示了这种行为是如何在整个半球的观察方向上连续推广。
位置编码
对于输入位置坐标,直接输入到网络里无法充分学习,因此需要将他们映射到高维空间。下面的γ函数是从R到高维空间的映射,将三维空间中的位置映射为高维度空间中的向量。值得一提的是,transformer里面的位置编码也是类似的。
体渲染
离散积分
对于任意一条射线,通过积分所有点的颜色即可获得这个方向渲染得到的密度和颜色。根据物理经验,我们希望一个点的密度越高,射线通过它之后变得越弱,也就是说密度和透光度呈反比。因此,一个点的密度越高,这点在这个射线下的颜色反应在像素上的权重越大。沿着这条射线积分得到像素颜色的公式如下:
颜色积分公式
其中T(t)表示从发射点到当前点的累积透射率,这保证射线经过了物体阻挡后,射线后方的物体颜色对最终的颜色影响非常小。
采样方法
积分是理想状态,实际上,我们通过采样射线上的点,获取密度值,将密度作为权重,对各个点的颜色进行加权求和。由于采样点非常多,计算复杂,我们使用分层采样方法,将[tn,tf]划分为N个均匀间隔的仓,然后从每个仓中随机抽取一个样。
从而积分公式可以改成
分层体积采样
再进一步,因为空间中的密度分布是不均匀的,射线均匀随机采样的话,渲染效率会比较低,因此我们训练两个辐射场网络,一个粗糙网络(Coares)一个精细网络(Fine)。粗糙网络是在均匀采样得到比较少的点进行渲染并训练的网络,用来输出wi进行采样概率估计。对wi进行归一化,把它看作是概率值,进行第二轮的精细采样。
损失函数
损失是粗略和精细渲染的渲染颜色和真实像素颜色之间的总平方,这里不用多说。
在每次优化迭代中,从数据集中的所有像素集中随机采样一批相机光线,计算损失。
补充的一些细节
网络结构:
文章参考了DeepSDF的框架,从网络结构可以看出,密度确实只和位置有关,和方向无关。颜色和方向有关。下图中的这个网络结构参数规模大约是百万级
NDC变换推导
文章末尾推导了将射线从相机空间映射到NDC空间(normalized device coordinate)的变换。文中做了这个变换关系的推导,我们不妨抄袭一下:
给出将射线从相机空间映射到NDC空间齐次坐标的标准三维透视投影矩阵:
其中n,f是近剪裁平面和远剪裁平面,r和t是场景在近剪裁平面上的右边界和上边界
我们把它作用于射线上的点,并应用图形学中的透视除法,除去第四个值:
做一个变量替换,这里我们希望找到一种简单的变换规则(也就是NDC坐标),用o’+t’d’描述:
t′=0和t=0是同一个点,可以消去一个自由度,得到o’:
代回上一个式子:
把一个只依赖于t的公共表达式分解出来,就得到了t’和d’:
请注意,根据需要,当t=0时,t′=0。t′→ 1时,t→ ∞. 回到原来的投影矩阵,我们的常数是:
使用标准针孔相机模型,我们可以重新参数化为:
在我们真正的前向捕捉中,我们假设远场景边界是无穷大的(因为NDC使用z维度来表示逆深度,即视差)。在这个极限中,z常数简化为:
最终NDC映射结果:
一旦我们转换为NDC射线,这允许我们简单地从0到1对t′进行线性采样,以便在原始空间中获得从n到∞的视差的线性采样。
应用:
当前版本可以用于新视角合成,但是也有问题,比如训练很慢,无法恢复几何结构。NERF在三维重建中的应用,还要等后面几篇出山。
新视角合成
看一下文中比较的论文,之前所有做新视角合成的方法都黯然失色。
文中用的指标是PSNR、SSIM、LPIPS,图像中的常用指标。
就到这里吧,其他几篇后续再更。