Mip NeRF思想注入与更多的NeRF方法

​ (未完成,请勿点击)。最近读了非常多关于NeRF的论文,毕竟这玩意从ECCV 2020被提出来之后就爆火了,变体层出不穷,基本上我能想到的卷法,都有人卷过了。低垂的果实总是被有能力又有准备的人先摘走,留下来的都是一些需要费大力气才能摘到的果实。论文不仅需要读,好的论文一定要复现,才能深入了解其精髓,西安交大人工智能学院的刘龙军副教授曾经在组会上说到:读论文不复现等于白读!大家都深以为然:>。而其中最有复现价值(并且难度没那么高的,不像Instant NGP,official repo代码都看不懂)的当属:

​ 其中Mip NeRF 360中的proposal network已经成为目前个人所实现的NeRF框架的基础。本文是复现过程中的一些心得以及对其他所读的NeRF论文的总结。

​ Neural surface reconstruction方法,利用多视角图片对表面进行建模。个人认为,这样的方法存在以下优点与缺点:

  • 已知NeRF对于density、法向量以及表面的建模非常垃圾(density云雾效应,表面建模非常粗糙、噪声很多,法向量非分块平滑)
  • 而对于表面的建模很有可能会使得半透明物体的建模能力下降(由于表面建模一般期望表面density较为集中)

​ 对于个人而言,本篇论文仅作为了解(知道对应的方法),并不准备实际使用类似的思想(个人更想对所有材质都能进行建模)。

​ NeuS中的RGB预测与NeRF一致,主要区别在于density以及weight的计算。NeuS就是希望density可以集中在表面附近,不产生云雾或者奇异的自遮挡,利用density求得的weight也需要具有一定的性质,主要是 无偏性(unbiased)以及 遮挡感知性(occlusion-aware)。对于NeRF而言,遮挡感知性是已经具备的性质,在weight的计算过程中,“accumulated transmittance”不断累乘(小于等于1的值),形成的weight在光线前段通过不透明物体时将显著降低,这样使得被遮挡的物体/表面不会影响渲染的结果。而NeRF的weight则不存在无偏性,由于正常情况下,density将会在表面附近存在峰值,而由于accumulated transmittance将使得weight发生移动(通常都是向前,特别是在表面附近的density较为分散时),使用这样的density无法估计出好的表面。

​ 作者的表面建模使用SDF进行表征(外正内负),作者使用名为S-density的函数作为表面附近density的分布。此density实际上是sigmoid函数的导数,计算较为简单: \[ \begin{align} \phi_s(t)=\frac{se^{-sx}}{(1+e^{-sx})^2},\label{wf}\\ \Phi_s(t)=\frac{1}{1+e^{-sx}}\\ w(t)=\frac{\phi_s(f(p(t)))}{\int_{-\infin}^{+\infin}\phi_s(f(p(u)))du}\label{weight} \end{align} \] ​ 由于我们实际需要设计一种同时具备无偏性以及遮挡感知性的weight,直接使用归一化的S-density显然是没有办法满足要求的(关于表面对称,不满足遮挡感知性)。作者先从无偏性出发,寻找一个不透明度density(opacity density),使得根据此density通过体积渲染计算的weight就是公式\(\eqref{wf}\)。可能此时有人会有疑问:不是说以公式\(\eqref{wf}\)确定的weight不具有遮挡感知性吗?作者在保证无偏性之后对此问题进行了讨论。首先,作者遵循NeRF的体积渲染公式: \[ \begin{equation}\label{derive1} T(t)\rho(t)=w(t),\text{ where }T(t)=\exp{\left(-\int_0^t\rho(u)du\right)} \end{equation} \] ​ 其中t是什么?是SDF函数值,在讨论无偏性时先讨论最简单的情况:平面单障碍物。单个平面障碍物的SDF很简单,就是\(-|\cos\theta|(t-t^*)\),其中\(t,t^*\)都代表光线方向的深度值,\(\theta\)为入射方向于平面法向量的夹角。则根据指数函数的性质以及平面的SDF公式,代入公式\(\eqref{weight},\eqref{derive1}\),可以得到: \[ \begin{equation} T(t)\rho(t)=|\cos\theta|\phi_s(f(p(t)))\mathop{\longrightarrow}^{T(t)\rho(t)=-\frac{dT}{dt}(t)}T(t)=\Phi_s(f(p(t))) \end{equation} \] ​ 也即得到accumulated transmittance的形式就是sigmoid函数。由公式\(\eqref{derive1}\)可以根据\(T(t)\),两边求对数后求导可以得到\(\rho(t)\)的表达式: \[ \begin{equation}\label{density} \rho(t)=\frac{-\frac{d\Phi_s}{dt}(f(p(t)))}{\Phi_s(f(p(t)))} \end{equation} \] ​ 根据此公式,按照NeRF渲染公式可以求出对称、无偏的weight(sigmoid导数的形式)。此后,作者考虑多个平面(区分物体表面内外),如下图所示:

​ 根据公式\(\eqref{density}\)知,由于\(d\Phi_s/dt\)的值域为正\(\mathbb{R}\),而: \[ \begin{equation} \frac{d\Phi_s(f(p(t)))}{dt}=\frac{d\Phi_s(u)}{du}\frac{du}{dt},\text{ where }u=f(p(t)) \end{equation} \] ​ 只有当\(f'(p(t))\)为正数时,\(\rho(t)\)才是正数,否则为负。负数是没有意义的,故我们将负数部分截断到0(背面“剔除”,光线穿过背面表面时,SDF是增加的,导数为正)。这样,被遮挡的部分(背面)将不会产生任何影响。此外,由于使用的公式仍然是NeRF的光线渲染公式,\(T(t)\)仍然从0开始积分到当前t,故经过几个障碍物的遮挡后,靠后方的weight会越来越小,这也是遮挡感知的一种体现。根据所推导的连续公式,将其离散化(实际上就是每两个点之间进行零阶保持,用quadrature近似积分)。

​ 虽然上述推导基于“平面物体”,但实际上对于光滑物体(一阶导连续),每个点都可以估计切平面(作为近似的法平面),也就可以利用平面物体推导的结果。则可以看出,使用NeuS的同时需要对法向量进行估计(如Ref NeRF中的两种方法,可以使用MLP预测法向量,也可以使用density的一阶梯度作为法向量,本论文中则可以用SDF梯度作为法向量)。

​ 一些关于NeuS的注意事项:

  • NeuS中的SDF函数是MLP(MLP近似了空间距离场),同时NeuS中也包含了一个层次化采样的NeRF模型(用于loss计算)。loss计算的逻辑流大概是这样:SDF MLP将会输出空间的SDF值,