Han Xu's blogs
  • 🥳欢迎!
  • Linux
    • 【Linux_install】详细的Ubuntu和win双系统安装指南
    • 【Linux】分区向左扩容的方法
    • 【Linux】挂载硬盘并设置开机自动挂载
    • 【Linux】grub命令行引导进入windows系统
    • 【Linux】python版本控制和环境管理
    • 【Linux】安装n卡驱动,美化gnome
    • 【Linux】gnome桌面环境切换KDE Plasma
  • python
    • 【matplotlib教程】数据可视化
    • 【python】实战:大批量数据的处理和拟合
    • 【Python爬虫】批量爬取图片的简单案例
    • 【scikit-opt】七大启发式算法的使用
    • 【综合评价方法】常见综合评价方法及其实现
    • 【python教程】打包和发布自己的项目,让别人去pip
    • 【PyTorch】n卡驱动、CUDA Toolkit、cuDNN全解安装教程
    • 【Pytorch教程】迅速入门Pytorch深度学习框架
    • 【稀疏矩阵】使用torch.sparse模块
  • C_C++
    • 【CMake】掌握CMake基本操作
    • 【计算机二级C++】题目与C++知识自检
  • matlab
    • 【Matlab】基础教程
  • 🤖ROS
    • 【ROS教程】安装ROS全流程及可能遇到的问题
    • 【ROS教程】用CLion编译和调试ROS包的全流程及可能遇到的问题
    • 【ROS教程】ROS文件系统和基础架构
    • 【ROS教程】ROS常用命令
    • 【ROS教程】话题通信
    • 【ROS教程】服务通信
    • 【ROS教程】ROS常用API讲解
    • 【ROS教程】编写launch文件
  • 📷Computer_Vision
    • Novel_View_Synthesis
      • 【NeRF】由浅入深介绍Neural_Radiance_Fields
      • 【CameraPoseRefinement】以BARF为例介绍三维重建中的位姿优化
      • 【3DGS】从新视角合成到3D_Gaussian_Splatting
      • 【NeRF】截至2024.12NeRF系列工作总结
    • SLAM
      • 【Survey】截至2024.12SLAM系列工作总结
    • OpenCV
      • 【OpenCV教程合集】一文入门和精通OpenCV(C_C++)
      • 【OpenCV教程】OpenCV中的数据类型
      • 【OpenCV教程】OpenCV中对矩阵的常用操作
      • 【OpenCV教程】对图像的各种常用操作
      • 【OpenCV教程】滤波和边缘检测的过程
      • 【OpenCV教程】如何优雅地画出一个几何图形
      • 【OpenCV教程】Trackbar到底怎么用?
      • 【OpenCV教程】轮廓检测过程
      • 【OpenCV教程】特征工程
  • 🗑️uncategorized
    • 【LaTex、markdown】常用语法写出漂亮的blog
    • 【git教程】快速掌握git
    • 【Internet Protocol】ip介绍,如何组局域网实现远程桌面和文件共享
    • 《周易》:大衍筮法
    • 【PyCharm】解决虚拟环境pip无法使用问题
    • 【git】解决能访问github但克隆不了的问题
    • 【Windows终端美化】为什么你的终端千篇一律?
Powered by GitBook
On this page
  • Plenoxels: Radiance Fields without Neural Networks
  • Voxel Grid with Spherical Harmonics
  • Optimization
  • NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction
  • Signed Distance Field Representation
  • Classical Volume Rendering
  • Volume Rendering with SDF
  • Training
  • Instant Neural Graphics Primitives with a Multiresolution Hash Encoding
  • Multiresolution Hash Encoding
  • Mip-NeRF: A Multiscale Representation for Anti-Aliasing Neural Radiance Fields
  • Cone Tracing
  • Positional Encoding
  • Architecture
  • Mip-Splatting: Alias-free 3D Gaussian Splatting

Was this helpful?

  1. Computer_Vision
  2. Novel_View_Synthesis

【NeRF】截至2024.12NeRF系列工作总结

Previous【3DGS】从新视角合成到3D_Gaussian_SplattingNextSLAM

Last updated 6 months ago

Was this helpful?

@


Plenoxels: Radiance Fields without Neural Networks

传统的nerf具有训练时间太长的缺点,因为nerf使用Position Encoding把大量信息存储在网络权重中,信息完全储存在网络中会导致计算很慢,网络表达能力也会受到限制。Plenoxels提出将场景表示为稀疏3D网络,在网络的格点上存储σ和球谐系数,并通过三线性插值的方法计算任意采样点的σ和球谐系数,从而取代了原本nerf中MLP的部分,实现了在渲染质量没有损失的情况下,比nerf优化速度快两个数量级。

Voxel Grid with Spherical Harmonics

Plenoxels在空间中建立一个这样的网络,网络的格点存储球谐系数和σ。对于空间中的一个样本点,Plenoxels寻找到最近的八个顶点,然后进行三线性插值,计算出这个采样点的对应球谐系数和σ。后续的体渲染过程与nerf相同。

稀疏3D网络是完全显式的方法,不含任何神经网络的成分,所有系数均直接优化,无需任何特殊的初始化或神经网络预训练。Plenoxels对每个格点使用2阶的球谐函数,也就是说,每个颜色通道有9个球谐系数。

Plenoxels比较了三线性插值和最近邻差值的性能差异,它认为三线性插值明显由于最近邻差值,以下是消融实验:

Method
PSNR ↑
SSIM ↑
LPIPS ↓

Trilinear, 256^3

30.57

0.950

0.065

Trilinear, 128^3

28.46

0.926

0.100

Nearest Neighbor, 256^3

27.17

0.914

0.119

Nearest Neighbor, 128^3

23.73

0.866

0.176

$256^3$和$128^3$是网格的分辨率。

Optimization

Plenoxels提出了自己的针对grid的Coarse-to-fine策略,即,在训练到一定阶段后,对grid进行上采样,例如,$256^3$的grid,每个网格一分八,变为$512^3$,在细分之后,网格的初始化值同样由三线性插值方法得到。

此外,Plenoxels也提及了剪枝操作。Plenoxels会根据grid的参数进行剪枝,仅关注非空的grid,剪枝策略是通过设定阈值实现的,阈值针对每个体素的:

Ti(1−exp⁡(−σiδi)).T_i \left( 1- \exp(- \sigma_i \delta_i) \right).Ti​(1−exp(−σi​δi​)).

文献还提出,直接进行修剪可能会最外层的参数造成不利影响,因为grid在后续的上采样时,这些参数还需要直接与外部的体素进行三线性插值。因此,Plenoxels使用膨胀操作,以确保仅在体素本身及其邻居都被视为未被占用时才对体素进行修剪。


Plenoxels根据均方误差(mean squared error, MSE)和全变分正则化(total variation regularization, TV)来优化grid的参数,前者很好理解,就是一个常规的loss,后者需要解释一下:

由于grid参数的优化是完全独立的,这很可能会导致训练过程中因为视角分布导致失真问题。譬如,某部分网格的参数能够很好的应付训练集视角的渲染,而另一部分网格由于前面的这些网格承担了大部分的渲染任务,使得它只存了较少的参数。在进行新视角合成的时候,这两部分网格参数的割裂感就会以伪影的形式展示出来。

因此,Plenoxel使用全变分正则化使相邻网格的参数变得平滑。

L=Lrecon+λTVLTV,Lrecon=1∣R∣∑r∈R∥C(r)−C^(r)∥22,LTV=1∣V∣∑v∈Vd∈[D]Δx2(v,d)+Δy2(v,d)+Δz2(v,d).\begin{aligned} \mathcal{L}&=\mathcal{L}_{recon}+\lambda_{TV}\mathcal{L}_{TV} ,\\ \mathcal{L}_{recon}& =\frac1{|\mathcal{R}|}\sum_{\mathbf{r}\in\mathcal{R}} \left \| C(\mathbf{r})-\hat{C}(\mathbf{r})\right \|_2^2 ,\\ \mathcal{L}_{TV}& =\frac{1}{|\mathcal{V}|}\sum_{\underset{d\in[D]}{\mathbf{v}\in\mathcal{V}}}\sqrt{\Delta_x^2(\mathbf{v},d)+\Delta_y^2(\mathbf{v},d)+\Delta_z^2(\mathbf{v},d)} . \end{aligned}LLrecon​LTV​​=Lrecon​+λTV​LTV​,=∣R∣1​r∈R∑​​C(r)−C^(r)​22​,=∣V∣1​d∈[D]v∈V​∑​Δx2​(v,d)+Δy2​(v,d)+Δz2​(v,d)​.​
Δx2表示(i,j,k)处体素的第d个值和(i+1,j,k)处体素的第d个值的误差的平方。\Delta_x^2表示(i, j, k)处体素的第d个值和(i+1, j, k)处体素的第d个值的误差的平方。Δx2​表示(i,j,k)处体素的第d个值和(i+1,j,k)处体素的第d个值的误差的平方。

对于无边界场景,Plenoxel的处理方法和NeRF++相似。Plenoxel用多球体图像(multi-sphere)表示外部空间,使用ERP投影(equirectangular Projction)将体素扭曲成球体,并在外部区域分为64层球壳,Plenoxel会预先缩放内部场景使其大致在单位球体中,越往外的球壳越大,最外一层球壳接近无穷,不同层之间可以进行插值,从而实现了外部的三线性插值。此外,外部区域的体素使用0阶的球谐函数,仅保留了RGB值,也就是说,背景部分的RGB不再依赖于视角。

在优化背景参数时,Plenoxel定义了一种基于柯西损失的稀疏先验来减少上采样时的质量损失:

Ls=λs∑i,klog⁡(1+2σ(ri(tk))2),σ(ri(tk))表示样本k沿着射线i的不透明度。\begin{array}{c} \mathcal{L}_s=\lambda_s\sum_{i,k}\log\left(1+2\sigma(\mathbf{r}_i(t_k))^2\right), \\ \sigma(\mathbf{r}_i(t_k))表示样本k沿着射线i的不透明度。 \end{array}Ls​=λs​∑i,k​log(1+2σ(ri​(tk​))2),σ(ri​(tk​))表示样本k沿着射线i的不透明度。​

在360°场景中,Plenoxel还使用beta分布的正则化器来优化σ:

Lβ=λβ∑r(log⁡(TFG(r))+log⁡(1−TFG(r))),r是训练光线,TFG(r)是累计前景透射率,值在0与1之间。很直观,一条光线要么只看到前景,要么只看到背景。\begin{array}{c} \mathcal{L}_\beta=\lambda_\beta\sum_\mathbf{r}\left(\log(T_{FG}(\mathbf{r}))+\log(1-T_{FG}(\mathbf{r}))\right) ,\\ \mathbf{r}是训练光线,T_{FG}(\mathbf{r})是累计前景透射率,值在0与1之间。 \\ 很直观,一条光线要么只看到前景,要么只看到背景。 \end{array}Lβ​=λβ​∑r​(log(TFG​(r))+log(1−TFG​(r))),r是训练光线,TFG​(r)是累计前景透射率,值在0与1之间。很直观,一条光线要么只看到前景,要么只看到背景。​

NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction

NeuS的目标是从多视角图像中重建高保真的物体表面,其本质是nerf的一种变体。NeuS首先说明了它的motivation:

  1. 基于Surface Rendering的神经隐式场景的重建方法无法应对物体表面深度突然变化的情况。

  2. 基于Volume Rendering的神经隐式场景的重建方法可以学习到物体表面深度突变的特征,但噪声很明显。

Neus解释说:

  1. Surface Rendering方法只是考虑每条射线与物体表面相交的单个交点(如a所示),从而无法重建具有复杂结构的物体表面(如b所示)。具体原因是,梯度只存在于射线与表面相交的这个单点,这对于有效的反向传播来说太局部了,并且当物体表面的深度发生突变时,优化会陷入不良的局部最小值。此外,Surface Rendering方法还需要前景掩膜作为收敛到有效表面的监督。

  2. Volume Rendering方法可以沿着射线的方向采样多个点(如a所示),因此可以应对物体表面突发的深度变化,所有的采样点,无论是表面附近还是远离表面,都会产生用于反向传播的梯度信号。然而,nerf的目的是新视角生成而不是表面重建,因此nerf只学习体积密度场,很难从中提取高质量的表面,如b所示,nerf学习的密度场尽管正确地解释了突然的深度变化,但它在某些平面区域中包含明显的噪声。

NeuS的贡献是在nerf的基础上修改了体渲染的策略,解决了nerf对表面重建不良的问题。

Signed Distance Field Representation

有符号距离场用f表示:

f:R3→R,f(x)表示空间中任意一点与最近表面的距离,x∈R3,若x在物体内部则为负数,x在物体外部则为正数。\begin{array}{c} f:\mathbb{R}^3 \rightarrow \mathbb{R}, \\ f(\mathbf{x})表示空间中任意一点与最近表面的距离,\mathbf{x} \in \mathbb{R}^3,\\ 若\mathbf{x}在物体内部则为负数,\mathbf{x}在物体外部则为正数。 \end{array}f:R3→R,f(x)表示空间中任意一点与最近表面的距离,x∈R3,若x在物体内部则为负数,x在物体外部则为正数。​

那么,可以用一个集合表示一个物体的表面:

S={x∈R3∣f(x)=0}.\mathcal{S}=\left\{\mathrm{x}\in\mathbb{R}^3|f(\mathbf{x})=0\right\}.S={x∈R3∣f(x)=0}.

Classical Volume Rendering

经典的体渲染公式如下:

C(o,v)=∫0+∞w(t)c(p(t),v)dt,{p(t)=o+tv∣t≥0},其中,o是相机光心位置,v是光线方向的单位向量,w(t)是点p(t)处的权重,c(p(t),v)是点p(t)处的颜色,C(o,v)是由相机光心位置和光线方向确定的像素坐标上的颜色输出值。\begin{array}{c} C(\mathbf{o},\mathbf{v})=\int_0^{+\infty}w(t)c(\mathbf{p}(t),\mathbf{v})\mathrm{d}t ,\\ \{\mathbf{p}(t)=\mathbf{o}+t\mathbf{v}|t\geq0\} ,\\ 其中,\mathbf{o}是相机光心位置,\mathbf{v}是光线方向的单位向量,\\ w(t)是点\mathbf{p}(t)处的权重,c(\mathbf{p}(t),\mathbf{v})是点\mathbf{p}(t)处的颜色,\\ C(\mathbf{o},\mathbf{v})是由相机光心位置和光线方向确定的像素坐标上的颜色输出值。\\ \end{array}C(o,v)=∫0+∞​w(t)c(p(t),v)dt,{p(t)=o+tv∣t≥0},其中,o是相机光心位置,v是光线方向的单位向量,w(t)是点p(t)处的权重,c(p(t),v)是点p(t)处的颜色,C(o,v)是由相机光心位置和光线方向确定的像素坐标上的颜色输出值。​

在nerf中,这个公式变成:

C(o,v)=∑i=1NTiσici,σi=(1−exp⁡(−σiδi)),Ti=exp⁡(−∑j=1i−1σjδj),δj=ti+1−ti,表示采样点之间的欧氏距离,σi和ci由多层感知机推出。\begin{array}{c} C(\mathbf{o},\mathbf{v})=\sum_{i=1}^{N}T_i\sigma_i\mathbf{c}_i, \\ \sigma_i=(1-\exp(-\sigma_i\delta_i)),T_i=\exp\left(-\sum_{j=1}^{i-1}\sigma_j \delta_j \right) ,\\ \delta_j = t_{i+1}-t_i,表示采样点之间的欧氏距离,\\ \sigma_i和c_i由多层感知机推出。 \end{array}C(o,v)=∑i=1N​Ti​σi​ci​,σi​=(1−exp(−σi​δi​)),Ti​=exp(−∑j=1i−1​σj​δj​),δj​=ti+1​−ti​,表示采样点之间的欧氏距离,σi​和ci​由多层感知机推出。​

以上式子是体渲染公式的离散化形式,所以会多出一个变量δ。可以看到,在nerf中,权重函数被设置为:

w(t)=T(t)σ(t),T(t)=exp⁡(−∫0tσ(u)du). w(t)=T(t)\sigma(t),T(t)=\exp(-\int_0^t\sigma(u)\mathrm{d}u).w(t)=T(t)σ(t),T(t)=exp(−∫0t​σ(u)du).

Volume Rendering with SDF

那么,SDF如何介入体渲染呢?直观上,我们认为σ应该在物体表面具有极大值,而物体表面S有具有f(x)=0的性质,我们自然想到使用最常用的logistics:

σ=Φs(x)=11+e−sx,对于物体表面的点x∈S,Φs(f(x))处于极大值。\begin{array}{c} \sigma=\Phi_s(x)=\frac{1}{1+e^{-sx}},\\ 对于物体表面的点\mathbf{x} \in \mathcal{S},\Phi_s(f(\mathbf{x}))处于极大值。 \end{array}σ=Φs​(x)=1+e−sx1​,对于物体表面的点x∈S,Φs​(f(x))处于极大值。​

但是,这样又会导致一些问题,被称为"Naive Solution"。NeuS提出了关于权重函数w(t)的两个原则:

1.无偏性(unbiased):当f(p(t))=0,w(t)应处于极大值。2.遮挡感知(Occlusion−aware):给定t0和t1,且f(p(t0))=f(p(t1)),t0<t1,那么,必有w(t0)>w(t1)。\begin{array}{c} 1.无偏性(unbiased):当f(\mathbf{p}(t))=0,w(t)应处于极大值 。\\ 2.遮挡感知(Occlusion-aware):给定t_0和t_1,\\ 且f(\mathbf{p}(t_0))=f(\mathbf{p}(t_1)),t_0 <t_1 ,\\ 那么,必有w(t_0)>w(t_1)。 \end{array}1.无偏性(unbiased):当f(p(t))=0,w(t)应处于极大值。2.遮挡感知(Occlusion−aware):给定t0​和t1​,且f(p(t0​))=f(p(t1​)),t0​<t1​,那么,必有w(t0​)>w(t1​)。​

关于第二点,翻译一下,就是如果出现一条光线上两个点SDF值相同时,距离相机更近的点应该具有更大的权重。

NeuS证明了如果使用Naive Solution,就不满足无偏性,于是NeuS提出了自己的w(t),并通过一些数学推导(本文从略),得到了σ(t)的表达式,为了与原式区分,文献中用ρ(t)表示:

w(t)=ϕs(f(p(t)))∫0+∞ϕs(f(p(u)))du,ρ(t)=−dΦsdt(f(p(t)))Φs(f(p(t))). w(t)=\frac{\phi_s(f(\mathbf{p}(t)))}{\int_0^{+\infty}\phi_s(f(\mathbf{p}(u)))\mathrm{d}u} ,\\ \rho(t)=\frac{-\frac{\mathrm{d}\Phi_s}{\mathrm{d}t}(f(\mathbf{p}(t)))}{\Phi_s(f(\mathbf{p}(t)))} .w(t)=∫0+∞​ϕs​(f(p(u)))duϕs​(f(p(t)))​,ρ(t)=Φs​(f(p(t)))−dtdΦs​​(f(p(t)))​.

T(t)仍然遵循与先前类似的形式:

T(t)=exp⁡(−∫0tρ(u)du).T(t)=\exp(-\int_0^t\rho(u)\mathrm{d}u).T(t)=exp(−∫0t​ρ(u)du).

另外,文章还提出,当光线出射(即f增大)时,ρ(t)会出现负值段,于是作者用最小值0截断,然后,ρ(t)变成:

ρ(t)=max⁡(−dΦsdt(f(p(t)))Φs(f(p(t))),0).\rho(t)=\max\left(\frac{-\frac{\mathrm d\Phi_s}{\mathrm dt}(f(\mathbf p(t)))}{\Phi_s(f(\mathbf p(t)))},0\right) .ρ(t)=max(Φs​(f(p(t)))−dtdΦs​​(f(p(t)))​,0).

w(t)效果如下,很直观地显示出了无偏性和遮挡感知:

Training

一条光线上采样点个数为n,批次数为m,损失函数定义为:

L=Lcolor+λLreg+βLmask,Lcolor=1m∑kR(C^k,Ck),R为L1损失,Lreg=1nm∑k,i(∥∇f(p^k,i)∥2−1)2,Lmask=BCE(Mk,O^k),BCE为交叉熵损失,MK∈{0,1},O^k=∑i=1nTk,iαk,i.\begin{array}{c} \mathcal{L}=\mathcal{L}_{color}+\lambda\mathcal{L}_{reg}+\beta\mathcal{L}_{mask} ,\\ \mathcal{L}_{color}=\frac{1}{m}\sum_k\mathcal{R}(\hat{C}_k,C_k),R为L1损失 ,\\ \mathcal{L}_{reg}=\frac1{nm}\sum_{k,i}(\|\nabla f(\hat{\mathbf{p}}_{k,i})\|_2-1)^2 ,\\ \mathcal{L}_{mask}=\mathrm{BCE}(M_k,\hat{O}_k),BCE为交叉熵损失,M_K \in \{0,1\} ,\\ \hat{O}_k=\sum_{i=1}^{n}T_{k,i}\alpha_{k,i} . \end{array}L=Lcolor​+λLreg​+βLmask​,Lcolor​=m1​∑k​R(C^k​,Ck​),R为L1损失,Lreg​=nm1​∑k,i​(∥∇f(p^​k,i​)∥2​−1)2,Lmask​=BCE(Mk​,O^k​),BCE为交叉熵损失,MK​∈{0,1},O^k​=∑i=1n​Tk,i​αk,i​.​

其中,$L_{color}$项很好理解,就是渲染得到的图片与输入图片之间的loss。$L_{reg}$用来正则化SDF的梯度,使其尽可能保持为1,确保了重建表面的光滑性和几何准确性,避免了由于梯度不规则而导致的重建瑕疵。$L_{mask}$表示遮罩损失,可以增强模型对物体形状和位置的捕捉精度。

Instant Neural Graphics Primitives with a Multiresolution Hash Encoding

InstantNGP的思想和Plenoxels有异曲同工的地方,它们都从3d grid出发,然后对空间中任意的采样点,使用线性插值的方法获得这个采样点对应的值。不同之处在于,Plenoxels是直接在grid的格点中存储球谐系数和σ,没有使用任何神经网络,是完全显式的表达。

InstantNGP沿用了Plenoxels的这种思想,但是并没有摒弃神经网络的成分。诚然,Plenoxels凭借稀疏的3d grid,将nerf的训练时间缩短了2个数量级。但是,3d grid这种结构化数据其实是很浪费的,因为只有物体表面的采样点是有意义的,绝大多数cell是空的。因此,InstantNGP并没有直接在网络的格点处去存储参数,而是根据格点在网络中的位置,建立了哈希表(hash table)进行映射(hash encoding),然后把映射出来的feature送到MLP里面再去训。

InstantNGP通过这种改良,宣称能用5秒完成nerf的训练!

Multiresolution Hash Encoding

以上就是哈希编码的简略过程,原文中使用的多分辨率哈希编码要多一些步骤。Plenoxels中的Coarse-to-fine策略是在训练中对grid进行上采样,而InstantNGP直接在最初就并存多分辨率的grid。

相关参数含义:

Parameter
Symbol
Value

Number of levels

L

16

Max. entries per level (hash table size)

T

$2^{14}$ to $2^{24}$

Number of feature dimensions per entry

F

2

Coarsest resolution

$N_{min}$

16

Finest resolution

$N_{max}$

512 to 524288

具体操作可分为以下5步:

  1. 划分出不同分辨率的L层grid。只需要确定最大分辨率和最小分辨率即可,中间的分辨率通过以下式子算出:

Nl:=⌊Nmin⁡⋅bl⌋,⌊⌋为向下取整。b:=exp⁡(ln⁡Nmax⁡−ln⁡Nmin⁡L−1).\begin{aligned} N_{l} & :=\left\lfloor N_{\min } \cdot b^{l}\right\rfloor,\lfloor \rfloor为向下取整。\\ b & :=\exp \left(\frac{\ln N_{\max }-\ln N_{\min }}{L-1}\right). \end{aligned}Nl​b​:=⌊Nmin​⋅bl⌋,⌊⌋为向下取整。:=exp(L−1lnNmax​−lnNmin​​).​
h(x)=(⨁i=1dxiπi) mod T,⨁表示按位异或。π1=1,对应x;π2=2654435761,对应y;π3=805459861,对应z。\begin{array}{c} h(\mathbf{x})=\left(\bigoplus_{i=1}^{d} x_{i} \pi_{i}\right) \quad \bmod T, \\ \bigoplus表示按位异或。\pi_{1}=1,对应x;\pi_{2}=2 654 435 761,对应y;\\ \pi_{3}=805 459 861,对应z。 \end{array}h(x)=(⨁i=1d​xi​πi​)modT,⨁表示按位异或。π1​=1,对应x;π2​=2654435761,对应y;π3​=805459861,对应z。​
  1. 根据输入坐标,在不同分辨率的网格下各自选取8个角点,进行d线性插值(𝑑-linear interpolation),

  2. 最终组装好的向量被送入MLP。

hash collision

每层grid的最大哈希槽为T,如果grid的resolution比较小,如图中所示,每个角点都有单一的哈希映射。但是,如果分辨率比较大,那么格点数就可能大于T,不同的角点有可能映射到哈希表上同一个位置,这被称为哈希冲突(hash collision)。

如果出现哈希冲突,那么InstantNGP不做任何处理,继续在这一层grid中使用同一个feature。这么做自然是有它的道理的,这就体现出多分辨率同时进行哈希映射的好处了。InstantNGP认为即便在这一层grid中,两个角点出现了哈希冲突,但是在其他分辨率中,这两个角点是不太可能再次出现哈希冲突的。而MLP的输入是所有层级分辨率的feature拼接起来的,所以MLP在学习的过程中是可以进行区分的。

此外,即便训练样本发生哈希冲突,也只有真正重要的点会主导MLP的优化。例如,nerf可见物体表面上的点将对重建图像有很大贡献(具有高可见度和高密度,两者都会显著影响梯度的大小),导致其表条目发生较大变化,而空白空间中的与其发生哈希冲突的点的权重将小得多。因此,更重要的样本的梯度占据主导地位,从而让真正重要的点的信息去支配网络的学习。

Mip-NeRF: A Multiscale Representation for Anti-Aliasing Neural Radiance Fields

NeRF在渲染过程中,在每个像素上使用单条光线对场景进行采样。如果在训练或测试图像内容时以不同分辨率观察场景,把相机拉进、拉远,图像就可能会产生锯齿(过度模糊或者混叠)。总的来说,NeRF只在相机位置固定、改变观察方向的视角生产上表现较好。

锯齿产生的本质原因是采样率低于真实原始信号的频率。解决这一现象有两个措施:一,尽可能提高采样率;二,使用低通滤波器去除大于奈奎斯特频率的成分,从而符合采样定律。

对于第一个措施,可以通过在每个像素上渲染多条光线来进行超级采样。但是,这样的直接解决方案对于NeRF来说是不切实际的,因为渲染每条光线需要查询多层感知器数百次,这会导致令人无法接受的计算代价。因此,Mip-NeRF选择了低通滤波器的方案。

Cone Tracing

MipNerf在Nerf的采样方式上作出了改进。Nerf在每个像素上射出一条光线,通过在光线上跳点进行采样。MipNerf把原本的一条射线变为一个圆锥体,选择跳点之间截取圆台进行采样。圆锥的半径是根据像素的物理尺寸再乘以$2\sqrt{12}$得到,作用是,使得圆锥被像素平面截取的面积近似于像素面积。

然后,需要采样的所有点的坐标如下:

F(x,o,d,r˙,t0,t1)=1{(t0<dT(x−o)∥d∥22<t1)∧(dT(x−o)∥d∥2∥x−o∥2>11+(r˙/∥d∥2)2)},dT(x−o)∥d∥22是计算向量在某方向上投影的公式。圆锥顶角θ:cos⁡θ=∥d∥2∥d∥2+r˙2=11+(r˙/∥d∥2)2,点x到圆锥顶点的连线与圆锥轴线的夹角α:cos⁡α=cos⁡⟨d,x−o⟩,只需cos⁡α>cos⁡θ,就可保证点在锥体内。\begin{array}{c} \mathrm{F}(\mathbf{x},\mathbf{o},\mathbf{d},\dot{r},t_0,t_1)=\mathbb{1}\left\{\left(t_0<\frac{\mathbf{d}^\mathrm{T}(\mathbf{x}-\mathbf{o})}{\left\|\mathbf{d}\right\|_2^2}<t_1\right) \wedge \left(\frac{\mathbf{d}^\mathrm{T}(\mathbf{x}-\mathbf{o})}{\left\|\mathbf{d}\right\|_2\left\|\mathbf{x}-\mathbf{o}\right\|_2}>\frac{1}{\sqrt{1+\left(\dot{r}/\left\|\mathbf{d}\right\|_2\right)^2}}\right)\right\} ,\\ \frac{\mathbf{d}^\mathrm{T}(\mathbf{x}-\mathbf{o})}{\left\|\mathbf{d}\right\|_2^2}是计算向量在某方向上投影的公式 。\\ 圆锥顶角\theta:\cos \theta=\frac{\left\|\mathbf{d}\right\|_2}{\sqrt{\left\|\mathbf{d}\right\|_2+\dot{r}^{2}}}=\frac{1}{\sqrt{1+\left(\dot{r}/\left\|\mathbf{d}\right\|_2\right)^2}} ,\\ 点\mathbf{x}到圆锥顶点的连线与圆锥轴线的夹角\alpha:\cos\alpha=\cos\left \langle \mathbf{d},\mathbf{x}-\mathbf{o} \right \rangle ,\\ 只需\cos\alpha > \cos \theta,就可保证点在锥体内。 \end{array}F(x,o,d,r˙,t0​,t1​)=1{(t0​<∥d∥22​dT(x−o)​<t1​)∧(∥d∥2​∥x−o∥2​dT(x−o)​>1+(r˙/∥d∥2​)2​1​)},∥d∥22​dT(x−o)​是计算向量在某方向上投影的公式。圆锥顶角θ:cosθ=∥d∥2​+r˙2​∥d∥2​​=1+(r˙/∥d∥2​)2​1​,点x到圆锥顶点的连线与圆锥轴线的夹角α:cosα=cos⟨d,x−o⟩,只需cosα>cosθ,就可保证点在锥体内。​

Positional Encoding

圆台体的位置编码定义为:

γ∗(o,d,r˙,t0,t1)=∫γ(x)F⁡(x,o,d,r˙,t0,t1)dx∫F⁡(x,o,d,r˙,t0,t1)dx,其中,γ(x)=(sin(20πx),cos(20πx),…,sin(2L−1πx),cos(2L−1πx).\begin{array}{c} \gamma^*(\mathbf{o},\mathbf{d},\dot{r},t_0,t_1)=\frac{\int\gamma(\mathbf{x})\operatorname{F}(\mathbf{x},\mathbf{o},\mathbf{d},\dot{r},t_0,t_1) d\mathbf{x}}{\int\operatorname{F}(\mathbf{x},\mathbf{o},\mathbf{d},\dot{r},t_0,t_1) d\mathbf{x}} ,\\ 其中,\gamma(\mathbf{x})=(sin(2^0\pi \mathbf{x}),cos(2^0\pi \mathbf{x}),\ldots,sin(2^{L-1}\pi \mathbf{x}), cos(2^{L-1}\pi \mathbf{x}) . \end{array}γ∗(o,d,r˙,t0​,t1​)=∫F(x,o,d,r˙,t0​,t1​)dx∫γ(x)F(x,o,d,r˙,t0​,t1​)dx​,其中,γ(x)=(sin(20πx),cos(20πx),…,sin(2L−1πx),cos(2L−1πx).​

然后,MipNerf用椭球去近似这个圆台:

σt:沿光线方向的方差。σr:垂直光线方向的方差。tμ=(t1+t0)/2,tμ=(t1−t0)/2,μt=tμ+2tμtδ23tμ2+tδ2,σt2=tδ23−4tδ4(12tμ2−tδ2)15(3tμ2+tδ2)2,σr2=r˙2(tμ24+5tδ212−4tδ415(3tμ2+tδ2)).\begin{array}{c} \sigma_t:沿光线方向的方差。\sigma_r:垂直光线方向的方差。 \\ t_\mu=(t_1+t_0)/2, t_\mu=(t_1-t_0)/2 ,\\ \mu_{t}=t_{\mu}+\frac{2t_{\mu}t_{\delta}^{2}}{3t_{\mu}^{2}+t_{\delta}^{2}} , \\ \quad\sigma_{t}^{2}=\frac{t_{\delta}^{2}}{3}-\frac{4t_{\delta}^{4}(12t_{\mu}^{2}-t_{\delta}^{2})}{15(3t_{\mu}^{2}+t_{\delta}^{2})^{2}} ,\\ \sigma_{r}^{2}=\dot{r}^{2}\left(\frac{t_{\mu}^{2}}{4}+\frac{5t_{\delta}^{2}}{12}-\frac{4t_{\delta}^{4}}{15(3t_{\mu}^{2}+t_{\delta}^{2})}\right). \end{array}σt​:沿光线方向的方差。σr​:垂直光线方向的方差。tμ​=(t1​+t0​)/2,tμ​=(t1​−t0​)/2,μt​=tμ​+3tμ2​+tδ2​2tμ​tδ2​​,σt2​=3tδ2​​−15(3tμ2​+tδ2​)24tδ4​(12tμ2​−tδ2​)​,σr2​=r˙2(4tμ2​​+125tδ2​​−15(3tμ2​+tδ2​)4tδ4​​).​

从而,得到世界坐标下的高斯表示:

μ=o+μtd,Σ=σt2(ddT)+σr2(I−ddT∥d∥22).\begin{array}{c} \boldsymbol{\mu}=\mathbf{o}+\mu_t\mathbf{d} ,\quad \boldsymbol{\Sigma}=\sigma_t^2(\mathbf{d}\mathbf{d}^\mathrm{T})+\sigma_r^2\Bigg(\mathbf{I}-\frac{\mathbf{d}\mathbf{d}^\mathrm{T}}{\left\|\mathbf{d}\right\|_2^2}\Bigg) . \end{array}μ=o+μt​d,Σ=σt2​(ddT)+σr2​(I−∥d∥22​ddT​).​

将位置编码写成矩阵形式并对高斯进行线性变换:

P=[1002002L−100010020⋯02L−10001002002L−1],γ(x)=[sin⁡(Px)cos⁡(Px)].μγ=Pμ,Σγ=PΣPT\begin{array}{c} \mathbf{P}=\begin{bmatrix} 1&0&0&2&0&0&2^{L-1}&0&0 \\ 0&1&0&0&2&0&\cdots&0&2^{L-1}&0 \\0&0&1&0&0&2&0&0&2^{L-1} \end{bmatrix}, \gamma(\mathbf{x})=\begin{bmatrix} \sin(\mathbf{P}\mathbf{x}) \\ \cos(\mathbf{P}\mathbf{x}) \end{bmatrix}. \\ \boldsymbol{\mu}_{\gamma} = \mathbf{P}\boldsymbol{\mu},\boldsymbol{\Sigma}_{\gamma}=\mathbf{P}\boldsymbol{\Sigma}\mathbf{P}^\mathbf{T} \end{array}P=​100​010​001​200​020​002​2L−1⋯0​000​02L−12L−1​0​​,γ(x)=[sin(Px)cos(Px)​].μγ​=Pμ,Σγ​=PΣPT​

接下来计算期望:

一元的情况:E⁡x∼N(μ,σ2)[sin⁡(x)]=sin⁡(μ)exp⁡(−(1/2)σ2),E⁡x∼N(μ,σ2)[cos⁡(x)]=cos⁡(μ)exp⁡(−(1/2)σ2),此处:γ(μ,Σ)=Ex∼N(μγ,Σγ)[γ(x)]=[sin⁡(μγ)∘exp⁡(−(1/2)diag⁡(Σγ))cos⁡(μγ)∘exp⁡(−(1/2)diag⁡(Σγ))].∘表示逐元素乘法\begin{array}{c} 一元的情况:\\ \operatorname{E}_{x\sim\mathcal{N}(\mu,\sigma^2)}[\sin(x)]=\sin(\mu)\exp\left(-(^1/2)\sigma^2\right) ,\\ \operatorname{E}_{x\sim\mathcal{N}(\mu,\sigma^2)}[\cos(x)]=\cos(\mu)\exp\left(-(^1/2)\sigma^2\right) ,\\ 此处: \\ \gamma(\boldsymbol{\mu},\boldsymbol\Sigma)=\mathrm{E}_{\mathbf{x}\sim\mathcal{N}(\boldsymbol{\mu}_\gamma,\boldsymbol{\Sigma}_\gamma)}[\gamma(\mathbf{x})] \\ =\begin{bmatrix}\sin(\boldsymbol{\mu}_\gamma)\circ \exp(-(1/2)\operatorname{diag}(\boldsymbol{\Sigma}_\gamma))\\ \cos(\boldsymbol{\mu}_\gamma)\circ\exp(-(1/2)\operatorname{diag}(\boldsymbol{\Sigma}_\gamma))\end{bmatrix} .\\ \circ表示逐元素乘法 \end{array}一元的情况:Ex∼N(μ,σ2)​[sin(x)]=sin(μ)exp(−(1/2)σ2),Ex∼N(μ,σ2)​[cos(x)]=cos(μ)exp(−(1/2)σ2),此处:γ(μ,Σ)=Ex∼N(μγ​,Σγ​)​[γ(x)]=[sin(μγ​)∘exp(−(1/2)diag(Σγ​))cos(μγ​)∘exp(−(1/2)diag(Σγ​))​].∘表示逐元素乘法​

其中:

diag⁡(Σγ)=[diag⁡(Σ),4diag⁡(Σ),…,4L−1diag⁡(Σ)]T,diag⁡(Σ)=σt2(d∘d)+σr2(1−d∘d∥d∥22).\begin{array}{c} \operatorname{diag}(\boldsymbol{\Sigma}_\gamma)=\left[\operatorname{diag}(\boldsymbol{\Sigma}),4\operatorname{diag}(\boldsymbol{\Sigma}),\ldots,4^{L-1}\operatorname{diag}(\boldsymbol{\Sigma})\right]^\mathrm{T} ,\\ \operatorname{diag}(\boldsymbol{\Sigma})=\sigma_t^2(\mathbf{d}\circ\mathbf{d})+\sigma_r^2{\left(1-\frac{\mathbf{d}\circ\mathbf{d}}{\left\|\mathbf{d}\right\|_2^2}\right)} . \end{array}diag(Σγ​)=[diag(Σ),4diag(Σ),…,4L−1diag(Σ)]T,diag(Σ)=σt2​(d∘d)+σr2​(1−∥d∥22​d∘d​).​

MipNerf的这种编码方式在文章中自称为Integrated Positional Encoding(IPE)。

Architecture

MipNerf准确描述了像素包含区域随着远近变化的关系。图中,Encodings从下到上表示从低频到高频,Encodings的高度取决了超参数L,可以看到,随着距离的增大,采样的圆台的范围也随之增加(即积分区域越大),又由于高频部分的周期很小(图中红色和蓝色的宽度),进而得到的IPE的积分在高频范围就变成了0,从而消除了高频的成分,Encoded Samples对应部分也变成了灰色。

原始的PE保留了所有的频率,因此特别依赖于超参数L。而IPE可以自适应地删除高频的成分,几乎不受L的影响。

Mip-Splatting: Alias-free 3D Gaussian Splatting

Wait for construction.

使用网格角点index的xyz坐标,根据如下式子进行哈希映射,产生一个feature。至于为什么哈希函数长这个样子,这个空间哈希函数其实是中提出的。

把不同分辨率网格下得到的不同的feature拼起来,再拼接上辅助输入(auxiliary inputs)。关于这个非空间的E维辅助输入,原文并没有直接说明是怎么计算的,而是说使用了中的和NeRF中的球谐函数基础。

📷
另外一篇文献
神经辐射缓存
one-blob编码
TOC