项目链接:https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/ 代码链接:https://github.com/graphdeco-inria/gaussian-splatting 论文链接:https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gaussian_splatting_low.pdf
3D 高斯椭球
- 很好的数学性质
- 仿射变换后高斯核仍然闭合
- 3D 降维到 2D 后(沿着某一个轴积分(z 轴))仍然为高斯
-
定义:
- 椭球高斯函数:
\[ G(x) = \frac{1}{\sqrt{2\pi^k|\Sigma|}}e^{-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)} \]其中\(\Sigma\)表示协方差矩阵,半正定,\(|\Sigma|\)是其行列式,\(\mu\)表示均量.
3D gaussian 为什么是椭球?
对于椭球高斯函数:
来说,
始终是一个常数,变量只存在于,
当
等于常数时,可展开为:
其中:
最终就是一个椭圆面的表示形式。而
是有取值范围的,所以整体表现出来就是一个实心的椭球体。
如何利用旋转和缩放计算协方差矩阵
对应于 cuda 代码中的 computeConv3D
高斯分布:
*\(\boldsymbol{x}\sim N(\mu, \Sigma)\)
* 均值:\(\mu_x, \mu_y, \mu_z\)
* 协方差矩阵:
高斯分布的仿射变换: \(\boldsymbol{w} = A\boldsymbol{x}+b\) \(\boldsymbol{w} \sim N(A\mu+b, A\Sigma A^T)\) * 协方差和 b 没有关系
标准高斯分布: *\(\boldsymbol{x} \sim N(\bold{0}, I)\) * 均值:\(\bold{0}\) 协方差矩阵:
*\(\boldsymbol{\Sigma} = \boldsymbol{A} \cdot \boldsymbol{I} \cdot \boldsymbol{A}^T\)任意高斯可以看作是标准高斯通过仿射变换得到
其中R是旋转矩阵,S是缩放矩阵,因此
Splatting 过程介绍——从 3D 到像素

投影变换

正交投影
- 对于一个立方体[l,r]×[b,t]×[f,n],将其平移到原点,然后缩放为[−1,1]×[−1,1]×[−1,1]的正方体
- 投影矩阵:

透视投影
有远小近大的原则,投影出来是一个锥体。因此需要先把锥体压成立方体,然后再进行正交投影,透视投影是非线性的,不是仿射变换。

视口变换
不管是透视投影还是正交投影,最终得到的都是\([-1, 1]^3\)范围内的立方体,然后进行视口变换将其映射回图片的大小 height * width,恢复出原始比例
3D 高斯的观测变换过程,如何把物理坐标系的物体映射到像素空间
第一步:从物理坐标系到相机坐标系 * 物理坐标系: * 高斯核的中心点:\(\boldsymbol{t}_k = [t_x, t_y, t_z]^T\) * 高斯核对应的高斯分布:\(r^{, , }_k(t) = G_{V_k^{, , }}(t-t_k)\) * 其中\(V_k^{, , }\)是协方差矩阵 * 相机坐标系: * 高斯核中心:\(\boldsymbol{\mu}_k = [\mu_x, \mu_y, \mu_z]^T\) * 高斯核对应的高斯分布:\(r^{, }_k(t) = G_{V_k^{, }}(\mu-\boldsymbol{\mu}_k)\) * 均值:\(\boldsymbol{\mu}_k = Wt_k+d\) * 协方差矩阵:\(V_k^{, } = WV_k^{, , }W^T\)
- 这一步就是简单做个仿射变换,3D 空间的坐标变换
第二步:从相机坐标系到像素空间 * 相机坐标系: * 高斯核中心:\(\boldsymbol{\mu}_k = [\mu_x, \mu_y, \mu_z]^T\) * 协方差矩阵:\(V_k^{, }\) * 投影变换:(非线性的变换,需要做泰勒展开做局部的线性近似) * 高斯核中心:\(\boldsymbol{x}_k = [x_x, x_y, x_z]^T\) * 高斯核对应的高斯分布:\(r_k(t) = G_{V_k}(x-\boldsymbol{x}_k)\) * 均值:& \boldsymbol{x}_k = m(\mu_k) &(对均值可以直接做非线性变换,不需要局部线性近似) * 协方差矩阵:\(V_k = \boldsymbol{J}V_k^{, }\boldsymbol{J}^T\) * 其中 \(\boldsymbol{J} = \frac{\partial m(\mu_k)}{\partial \mu}\) 为雅可比矩阵 * 至此,协方差矩阵\(V_k = \boldsymbol{J}WV_k^{, , }W^T\boldsymbol{J}^T\)
如何求得雅可比矩阵?
已知:
视锥中一个点:\([x y z 1]^T\)对其应用投影变换后:
由此,雅可比矩阵为:
3D 高斯球的颜色表示
把高斯椭球的颜色表示成了一个颜色球,这个颜色球从不同角度观察,都可以看到不同的颜色。但是颜色球的颜色应该怎么描述呢?这里就是使用球谐函数来对其做近似,然后从不同角度对其做渲染

球谐函数
- 任何一个球面坐标的函数,都可以用多个球谐函数来近似 *\(f(t) \approx \sum_l\sum^l_{m=-l}c_l^my_l^m(\theta, \phi)\)
- 其中,l表示当前的阶数,\(c_l^m\)是各项系数,\(y_l^m\)是基函数

- 其中各个基函数为:
- 由此,当 xyz 固定时,基函数就是固定的,但是系数是变化的。当系数维度为 3 时,共有 16 个系数,即一个高斯球,有 16 个颜色系数要估计
使用 α-blending 计算像素的颜色
与 NERF 中公式相同
其中: \(T_i\):在 s 点之前,光线没有被阻挡的概率 \(\alpha_i\):在 s 点处,光线被遮挡的概率。包含两点:1. 高斯椭球本身的不透明度;2. 该像素点距离高斯椭球中心越远,高斯椭球对其影响越小 \(c_i\):在 s 点处,高斯球的颜色。即通过球谐函数近似得到的颜色
注意,此时是在 2D 平面上计算像素值
当一轮迭代之后,参数都固定了,此时就可以计算像素的颜色值。3D 高斯在投影到 2D 平面上后,还是一个高斯分布。利用之前的理论,当:
时,在二维上表现为一个椭圆:
此时\(\mu_1\)和\(\mu_2\)为高斯中心点在像素平面上的坐标,\(\sigma_1\)和\(\sigma_2\)为二维高斯协方差矩阵对角线上的元素。
高斯椭球的自适应密度控制
- 这里使用 α 值来调控高斯函数的数量,以防止在优化过程中创建过多的高斯函数。α 值的调整基于一个预定义的阈值,当高斯函数的数量超过这个阈值时,就会使用剔除机制来移除那些贡献较小的高斯函数。(这里可以仔细在源码里找找)
- 此外,为了处理小规模几何结构的不足重建问题,采用了复制(在重建不足的区域)和分裂(在过度重建的区域)高斯函数的策略。这些操作使得优化过程能够更精细地调整高斯函数的分布,以更精确地匹配场景的几何结构。具体地,这个过程包括以下步骤: 在重建不足的区域,如果小尺度的几何特征没有被足够覆盖,算法会克隆现有的高斯函数,即复制一个相同的高斯函数以增加局部密度,从而更好地捕捉细微的细节。 对于过度重建的区域,如果小尺度的几何被一个大的高斯函数所覆盖,算法会将其分裂为两个较小的高斯函数,这样可以减少单一高斯函数覆盖过多细节的情况,避免模糊和不必要的重叠。
- 这种自适应的密度控制策略不仅可以增加细节的丰富性,也有助于避免过多的高斯函数对计算资源的消耗。α 值的动态调整和高斯函数的合理分布,使得模型在不同的迭代中逐渐收敛,最终得到一个既紧凑又精确的 3D 场景表示。
- 优化过程中,通过增加 α 值来提高某些高斯函数的重要性,同时允许采用剔除方法来移除那些低于预设 α 阈值的高斯函数。尽管高斯函数可能会随着优化过程中的调整而增大或缩小,并与其他高斯函数产生重叠,但作者定期进行重建和调整,以确保在视觉空间中保留有重要贡献的高斯函数,同时优化整体的几何表现。
- 通过这种方法,3D Gaussians 作为欧几里得空间中的基元,在所有时间内都保持一致,与其他方法(如基于投影或扭曲的策略处理大型高斯函数的方法)相比,这种方法避免了复杂的变换,使得渲染过程更加直接和高效。 代码解析
Reference
[0] https://fansaorz.github.io/2024/04/13/3D-Gaussian-Splatting%E8%AF%A6%E8%A7%A3/ [1] https://www.bilibili.com/video/BV1cz421872F