@TOC
新视角合成(Novel View Synthesis),属于计算机视觉领域,该任务要求:
最终获得:
无论是2020ECCV的best paper,NeRF,还是2023年爆火的3DGS,都是为了完成NVS任务。
这两个步骤是新视角合成的基本框架,涵盖了几何重建和图像合成的关键概念。在实践中,可以根据具体应用的需求进一步细化这些步骤,例如加入光照模型、深度合成等处理,以提高合成图像的质量和真实感。
让我们来以NeRF为例子,更加深刻地了解一个新视角合成任务的步骤。当然,笔者不会写的特别详细,否则这篇文章就变成NeRF的介绍了。如果对NeRF特别感兴趣,可以阅读笔者的另一篇文章。
NeRF成功最大因素就在于它借用了深度学习的东西去进行三维重建。简单地说,NeRF利用多层感知机(MLP)创建了一个函数。
这个函数接受一个向量(x,y,z,θ,ϕ)(x,y,z,\theta,\phi )(x,y,z,θ,ϕ)作为输入,其中,(x,y,z)(x,y,z)(x,y,z)表示这个点在空间中的坐标,(θ,ϕ)(\theta,\phi )(θ,ϕ)表示观察角度(俯仰角pitch和偏航角yaw)。它的输出是(RGB,σ)(RGB,\sigma )(RGB,σ)。RGB很好理解,就是这个点的颜色。而σ\sigmaσ,是一个被称为体素密度的计算量。这两个输出的量是为了后面的体渲染做准备。
有了这个函数之后,对于三维空间中指定坐标的任何一点,都可以知道它的(RGB,σ)(RGB,\sigma )(RGB,σ)。而且,由于使用的是MLP来表示这个函数,那么这个函数就是连续的、可微分的,也就可以用反向传播去优化。
NeRF的渲染方式采用经典的体渲染。具体的算法本文不再赘述。总而言之,体渲染需要三个参数作为输入:
然后输出:
当然,这种方法也是可微的。
这种体渲染的方式需要以像素为单位生成光线,然后在光线上对空间内的点进行采样,因此,每个像素点在渲染时都需要计算对应的光线,成本相当高昂,在渲染高分辨率图像时帧率非常低下,无法做到实时渲染。
同样基于这个原因,NeRF优化参数时,在源图像与生成图像上只会选择一些像素点,去计算RGB颜色值的损失,进行反向传播,优化MLP的参数,而不是将所有像素点都拿来计算损失。
3DGS使用SFM(Structure from Motion)方法完成了从一组图片估计点云的步骤,甚至不需要给出相机的位姿就可以获得点云。这是一种非常成熟的方法,由Schönberger和Frahm等人于2016年提出,已经封装在COLMAP库中,在3DGS开源的代码中可以直接调用。
此方法的具体内容不是本文要探讨的,可阅读原文献。
3DGS从获得的稀疏点云开始,创建并且优化高斯点云
。每个高斯点包含以下几个用来渲染的重要属性:
球谐函数(Spherical Harmonics, SH)是一组定义在球面上的特殊函数,通常用来表示球面上的函数。球谐函数在图形学、计算机图形学和计算机图像等领域中广泛应用。在3DGS中,球谐函数用于近似光照和颜色分布。
虽然球谐函数是定义在球面上,但是这个函数的输入并不是坐标(x,y,z)(x,y,z)(x,y,z),而是视角(θ,ϕ)(\theta,\phi )(θ,ϕ),它的输出是RGB颜色值。
只要给定了欲生成图片的目标位姿之后,就可以知道这个点对应的视角(θ,ϕ)(\theta,\phi )(θ,ϕ),从而根据这个函数计算这个点在图片上应该呈现出的颜色。因此,球谐函数的参数也是优化的目标之一。
论文中,损失函数定义如下:
L=(1−λ)L1+λLD-SSIM \mathcal{L}=(1-\lambda) \mathcal{L}_{1}+\lambda \mathcal{L}_{\text {D-SSIM }} L=(1−λ)L1+λLD-SSIM
其中,L1\mathcal{L}_{1}L1是实际图片与渲染图片的像素值的L1范数;LD-SSIM \mathcal{L}_{\text {D-SSIM }}LD-SSIM 是Depth-aware Structural Similarity (D-SSIM) 损失,是一种基于结构相似性(SSIM)的损失函数,但考虑了深度信息。SSIM 用于衡量两幅图像在结构、亮度和对比度上的相似性。公式如下:
LD−SSIM=1−(2μI^μI+C1)(2σI^I+C2)(μI^2+μI2+C1)(σI^2+σI2+C2) \mathcal{L}_{D-SSIM} = 1 - \frac{(2\mu_{\hat{I}} \mu_I + C_1)(2\sigma_{\hat{I}I} + C_2)}{(\mu_{\hat{I}}^2 + \mu_I^2 + C_1)(\sigma_{\hat{I}}^2 + \sigma_I^2 + C_2)} LD−SSIM=1−(μI^2+μI2+C1)(σI^2+σI2+C2)(2μI^μI+C1)(2σI^I+C2)
其中:
然后,作者使用Adam一阶优化器进行优化。
论文中,作者提出分裂高斯点的方法可能会导致密度的不合理增加。
In the first case we detect and treat the need for increasing both the total volume of the system and the number of Gaussians, while in the second case we conserve total volume but increase the number of Gaussians. Similar to other volumetric representations, our optimization can get stuck with floaters close to the input cameras; in our case this may result in an unjustified increase in the Gaussian density.
于是,作者设置了以下策略:
阈值删除策略
也可以很好地剔除几乎透明的高斯点。这里的N
同样是个超参数。笔者主要参考了此篇综述。
NeRF通过体渲染去生成新的图像,这要求为每个像素都采样很多空间点。这种方法在高分辨率的图像合成中计算成本非常高昂,难以实现实时渲染速度。
与之形成鲜明对比的是,3DGS首先将空间中的3D高斯投影到基于像素的图像平面上,这个过程被称为泼溅(splatting)。随后,3DGS对这些高斯进行排序并计算每个像素的值。
3DGS的渲染分为以下几步:
KaTeX parse error: Expected 'EOF', got '\boldsymbol' at position 18: …Sigma^{\prime}=\̲b̲o̲l̲d̲s̲y̲m̲b̲o̲l̲{J} \boldsymbol…
其中,KaTeX parse error: Expected 'EOF', got '\boldsymbol' at position 1: \̲b̲o̲l̲d̲s̲y̲m̲b̲o̲l̲{J}是射影变换的仿射近似的雅可比矩阵。对应代码。
C=∑i∈Nciαi′∏j=1i−1(1−αj′) C=\sum_{i\in\mathcal{N}}c_i \alpha_i^{\prime}\prod_{j=1}^{i-1}\left(1-\alpha_j^{\prime}\right) C=i∈N∑ciαi′j=1∏i−1(1−αj′)
其中,cic_ici是球谐函数输出的颜色,最终的不透明度αi′\alpha_i^{\prime}αi′是学习到的不透明度αi\alpha_iαi和高斯分布的乘积结果(对应代码),对应计算公式如下:
KaTeX parse error: Expected '\right', got '\boldsymbol' at position 64: …c12(x^{\prime}-\̲b̲o̲l̲d̲s̲y̲m̲b̲o̲l̲{\mu}_i^{\prime…
其中,x′x^{\prime}x′和KaTeX parse error: Expected 'EOF', got '\boldsymbol' at position 1: \̲b̲o̲l̲d̲s̲y̲m̲b̲o̲l̲{\mu}_i^{\prime…是投影空间中的坐标。
值得担忧的是,与NeRFs相比,上述的渲染过程可能更慢,因为生成所需的有序列表难以并行化。实际上,这种担忧是合理的;当使用这种简单的逐像素方法时,渲染速度可能会受到显著影响。为了实现实时渲染,3DGS做出了几个妥协,以适应并行计算。
Tiles
(图像块)。为了避免为每个像素计算有序列表的计算成本,3DGS将精度从像素级别转移到块级别细节,如(b)所示。3DGS最初将图像划分为多个不重叠的图像块,这些图像块在原始论文中被称为tiles。每个块包含16x16像素。3DGS进一步确定哪些图像块与这些投影的高斯(椭圆)相交。考虑到一个投影的高斯可能覆盖多个块,一种合理的方法是复制高斯,为每个副本分配一个标识符(即块ID),如(c)所示。一般来说,一个复杂场景需要由数百万个高斯点表示。因此,3DGS的每个场景都需要GB级别的存储空间。相比之下,NeRF的一个场景只需要MB级别的空间。
本文由博客一文多发平台 OpenWrite 发布!