加载高斯点参数
在这篇文章中,我们开始把之前的点云光栅化“升级”为高斯光栅化。我们将加载经过预训练的盆栽(Bonsai)场景参数,并对现有的代码结构进行一次大扫除,为接下来的复杂渲染做好准备。
本章的完整代码可以查看 Commit 55bf6d6。
更丰富的高斯点参数
在之前的简易点云渲染中,我们只关心两个参数:位置(Position)和颜色(Color)。
但在真正的高斯溅射中,每一个高斯球都拥有更丰富的生命力。现在我们需要引入以下参数:
- 缩放比例(Scale)
- 旋转(Rotation)
- 不透明度(Opacity)
- 球面谐波(Spherical Harmonics, 代表颜色特征)
为什么不直接优化协方差?因为决定一个 3D 高斯形状的是它的协方差矩阵(Covariance Matrix)。但是在反向传播优化时,协方差矩阵必须保持半正定(半正定矩阵才能代表一个有效的几何椭球体)。直接优化它很容易产生不符合数学和物理意义的“坏死”参数。因此,我们采用一种重新参数化的策略:通过优化缩放(Scale)和旋转(Rotation),再由它们来间接计算协方差。
其核心数学公式为:
其中
代码实现
在编写新的光栅化函数前,我们首先要做一个检查,看看预训练好的高斯参数是不是正常的。
- # 1. 加载优化好的高斯参数 (位置和SH DC系数)
- print("Loading optimized Gaussian parameters...")
- pos = torch.from_numpy(torch.load("datasets/out_bonsai/pos_param.pt")).float()
- f_dc = torch.from_numpy(torch.load("datasets/out_bonsai/f_dc.pt")).float()
fdc 本质上并不是直观的 RGB 颜色,而是表达颜色的球面谐波系数。如果直接把它当做颜色渲染,画面会显得非常怪异。
- # 2. 根据SH DC系数计算颜色
- # SH DC常数 Y_0^0 = 1 / (2 * sqrt(pi)) ≈ 0.28209479177387814
- sh_constant = 0.28209479177387814
- colors = torch.sigmoid(sh_constant * f_dc)
当我们运行可视化代码,并尝试以正常分辨率进行光栅化时,会发现显著的差异。
以前我们渲染 SFM(运动恢复结构)生成的初始点云时,盆栽在画面中稀稀拉拉,几乎看不清轮廓;但现在,哪怕在高分辨率下,盆栽也变得很稠密。
这是因为高斯泼溅在优化过程中执行了稠密化策略(Densification Strategy)。算法会在需要表现细节的地方(如画面中心的盆栽实体)克隆并分裂出成千上万个新的高斯球。正是这种“一生二、二生三”的机制,填补了场景的空隙,造就了连续且逼真的视觉效果。
代码重构
为了迎接接下来的渲染代码,我们需要将辅助函数剥离出去。我们创建一个名为 util.py 的文件,并将以下“后勤”函数迁移进去:
1. project_points(点投影函数)
2. load_cameras(相机加载函数)
3. quat_to_rotmat(四元数转旋转矩阵函数)