流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

多张图片 + 相机参数

用 COLMAP 得到相机位姿和稀疏点云

用稀疏点云初始化一堆 3D Gaussian

从某个相机视角把 Gaussian 渲染成图片

和真实图片比较,计算 loss

反向传播优化 Gaussian 的位置、大小、颜色、不透明度

不断增删 Gaussian

得到可以实时新视角渲染的 3D 场景

核心链路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

COLMAP 点云

初始化 3D Gaussians

选择相机视角

外参:世界坐标 → 相机坐标

内参:相机坐标 → 像素坐标

3D Gaussian 投影成 2D 椭圆

深度排序

alpha blending

渲染图

和真实图计算 loss

反向传播优化 Gaussian

densify / prune

最终 3D Gaussian 场景

COLMAP 流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

图片

特征提取

特征匹配

几何验证

增量式 SfM (选择初始图像对 , 根据匹配点估计两台相机之间的相对姿态)

三角化生成稀疏点云

Bundle Adjustment 联合优化

输出相机参数 + 相机位姿 + 稀疏点云

Gaussian 参数

参数作用
mean / xyzGaussian 在 3D 空间中的中心位置
scaleGaussian 在三个方向上的大小
rotation / quaternionGaussian 椭球的朝向
opacity不透明度
color / SH颜色,通常用球谐函数表示视角相关颜色

训练

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

gaussians = init_from_colmap_points()
cameras = load_colmap_cameras()
images = load_training_images()

for iter in range(num_iterations):

# 1. 随机选择一个训练视角
camera = random_choice(cameras)
gt_image = camera.gt_image

# 2. 用当前 Gaussian 从该视角渲染图像
render_image = render(gaussians, camera)

# 3. 和真实图像比较
loss = l1_loss(render_image, gt_image) + ssim_loss(render_image, gt_image)

# 4. 反向传播
loss.backward()

# 5. 更新 Gaussian 参数
optimizer.step()
optimizer.zero_grad()

# 6. 定期增加 / 删除 Gaussian
if iter in densification_stage:
densify_and_prune(gaussians)