基于深度学习的三维重建主流技术简要介绍

注:本博文存在AI生成内容

VAE技术

VAE假设隐变量服从某种分布,其编码器负责输出这种分布(一般都是正态分布),解码器从该分布中采样出隐变量再重构原始数据。
通过这种方式,VAE强迫模型学习潜在分布接近先验分布,从而保证潜在空间的连续性和完整性。

重采样的过程,实际上\(z=\mu+\sigma\odot\epsilon\)通过一个标准正态分布的随机噪声实现,\(\mu\)\(\sigma\)作为可学习参数确保梯度反向传播有效。

损失函数通常由两部分组成:

\[\mathcal{L} = \underbrace{\text{Reconstruction Loss}}_{\text{重建项}} + \underbrace{\text{KL Divergence}}_{\text{正则项}} \]

KL散度:衡量编码器学到的分布 \(q_\phi(z|x)\) 与先验分布 \(p(z)\)(通常为标准正态分布 \(\mathcal{N}(0, I)\))之间的差异。对于高斯分布,KL 散度有解析解:

\[D_{KL} = -\frac{1}{2} \sum_{j=1}^{J} (1 + \log(\sigma_j^2) - \mu_j^2 - \sigma_j^2) \]

其中 \(J\) 是隐变量的维度。

选择VAE的原因,简单且训练稳定,耗时低。

Stable Diffusion技术

初期阶段:
在开始之前需要有一个针对图像编码和解码的VAE,VAE负责学习潜在的图像编码空间,以便于给后续扩散去噪过程在这个固定的潜在空间里操作。

训练阶段:

  1. 用自编码器把输入图片从像素空间映射到隐向量空间,把 RGB 图片转换到隐式向量表达。
  2. 用冻结参数的CLIP完成文本嵌入。
  3. 对输入图像的隐式向量施加不同强度噪声,再把加噪后隐向量输入到 UNet 来输出预估噪声,和真实噪声信息标签作比较来计算 KL 散度损失,并通过反向传播算法更新 UNet 模型参数;引入文本嵌入后,UNet 在训练时把其作为 condition,就是利用注意力机制来更好地引导图像往文本向量方向生成;

UNet就是训练来区分图片语义信息和噪声信息

采样阶段:包含了CLIP和采样器迭代:

  1. 用冻结参数的CLIP完成文本嵌入;
  2. 利用随机种子随机生成噪声隐向量,利用训练好的 UNet 模型,结合不同采样器(如 DDPM/DDIM/PLMS)迭代 T 次不断去除噪声,得到具有文本信息的隐向量;
  3. 用解码器把之前得到的图像隐向量进行解码,得到被映射到像素空间的生成图像。

DDPM基于马尔可夫链

NeRF技术

NeRF:使用一个深度神经网络来隐式地表示3D场景,而不是传统的网格(Mesh)、点云(Point Cloud)或体素(Voxel)来表示3D物体*

隐式表示

NeRF将3D场景编码在一个神经网络的权重中以学习连续函数:

\[F_\Theta: (x, y, z, \theta, \phi) \rightarrow (RGB, \sigma) \]

  • 输入:空间坐标 \((x, y, z)\) 和观察方向 \((\theta, \phi)\)
  • 输出:该位置的体积密度(\(\sigma\))和颜色(\(RGB\),表示从该方向看过去的颜色)。

算法流程

  1. 数据输入:不同视角位姿的2D照片。
  2. 光线投射(Ray Marching):对于每张训练图片中的每个像素,算法向场景中发射一条光线。
  3. 采样查询:沿着这条光线采样多个点,将这些点的坐标和光线方向输入到神经网络中,网络预测每个点的颜色和密度。
  4. 体积渲染:利用经典的体积渲染公式,将光线上所有采样点的颜色和密度累积起来,计算出该像素的最终预测颜色。采用分段近似渲染方法,分为粗采样和精采样。
  5. 优化:比较预测颜色与真实照片像素颜色的差异(损失函数),通过反向传播更新神经网络的权重,直到网络能完美复现输入的所有照片。

体积渲染公式

可将这条射线的颜色,用积分的方式表示为:

\[C(\mathbf{r}) = \int_{t_n}^{t_f} T(t) \cdot \sigma(\mathbf{r}(t)) \cdot \mathbf{c}(\mathbf{r}(t), \mathbf{d}) \, dt \]

其中,$ T(t) $ 表示的是射线从 $ t_n $ 到 $ t $ 这一段的累计透明度,即该射线从 $ t_n $ 到 $ t $ 都没有因击中任何粒子而被停下的概率,具体写作:

\[T(t) = \exp\left(-\int_{t_n}^{t} \sigma(\mathbf{r}(s)) \, ds\right) \]

在连续的辐射场中,针对任意视角进行渲染,就需要对穿过目标虚拟相机的每个像素的射线,求取上述颜色积分,从而得到每个像素的颜色,渲染出该视角下的成像图片。

分段近似渲染方法(体积渲染公式离散化)

首先将射线需要积分的区域 \([t_n, t_f]\) 均匀分为 \(N\) 份,再在每个小区域进行均匀随机采样。之前预测颜色 \(C(\mathbf{r})\) 的积分,可以简化为求和的形式:

\[\hat{C}(\mathbf{r}) = \sum_{i=1}^{N} T_i \cdot \left(1 - \exp(-\sigma_i \cdot \delta_i)\right) \cdot \mathbf{c}_i \]

其中,\(\delta_i\) 为两个近邻采样点之间的距离,此处 \(T(t)\) 改写作:

\[T_i = \exp\left(-\sum_{j=1}^{i-1} \sigma_j \delta_j\right) \]

实际上使用分层采样的核心是用两级抽样

  1. 均匀采样(粗采样)。等分采样。
  2. 得到密度概率。通过Coarse网络,计算采样点的密度\(\sigma\)
  3. 构造概率密度函数PDF。

\[w_i = T_i (1 - \exp(-\sigma_i \delta_i)) \quad (\text{即每个点对最终颜色的贡献权重})\\ \hat{w}_i = \frac{w_i}{\sum_{j} w_j} \quad (\text{归一化为概率}) \]

  1. 计算累积分布函数CDF.

\[\text{CDF}_i = \sum_{j=1}^{i} \hat{w}_j \]

  1. 在PDF上采样新的若干个点(精采样)
    \([0, 1]\) 区间内均匀生成 \(N_f\) 个随机数 \(u_k\),找到每个 \(u_k\) 在 CDF 中对应的位置,通过线性插值反推出对应的位置。

位置信息编码

神经网络倾向于学习低频函数,导致“频谱偏差”(Spectral Bias)难拟合高频信号。
对此NeRF 将原始坐标 \((x, y, z)\) 映射到一个更高维的特征空间,不需要自己去专门学习高频特征,而是直接在这些现成的波上进行线性组合:

\[\gamma(p) = \left( p, \sin(2^0 \pi p), \cos(2^0 \pi p), \sin(2^1 \pi p), \cos(2^1 \pi p), \dots, \sin(2^{L-1} \pi p), \cos(2^{L-1} \pi p) \right) \]

其中:

  • \(p \in \{x, y, z\}\)
  • \(L\) 是频率的层数(在原始 NeRF 中,位置编码 \(L=10\),方向编码 \(L=4\))。
  • 这个函数将原本的 1个标量 变成了 \(2L + 1\) 个值

优缺点

优点:图片质量高、纹理细节保留好
缺点:训练和渲染速度慢

高斯泼溅技术

算法流程

  1. 初始化点云:使用传统摄影测量法(如COLMAP)从输入图片集恢复稀疏点云,将每个点初始化为一个3D高斯体。
  2. 迭代优化
    • 前向传播:将当前所有3D高斯体投影到当前视角的2D平面,进行光栅化渲染生成图像。
    • 计算损失:比较渲染图像与真实拍摄图像的差异。
    • 反向传播:计算梯度,更新所有高斯体的参数(位置、形状、颜色、透明度)。
    • 密度控制:每隔一定步数,根据梯度统计结果执行分裂、克隆或删除操作,调整高斯数量。

将空间中的的高斯球点云投影到指定视角屏幕上,每个高斯球有4个属性:

  1. 中心位置 \(\boldsymbol{\mu}_i \in \mathbb{R}^3\):高斯体的中心坐标。
  2. 协方差矩阵 \(\boldsymbol{\Sigma}_i \in \mathbb{R}^{3 \times 3}\):控制高斯体的形状(大小)和方向(旋转)。
  3. 不透明度 \(\alpha_i \in [0, 1]\):控制该高斯体的可见程度。
  4. 颜色系数 \(\mathbf{c}_i\):通常使用球谐函数(Spherical Harmonics, SH)系数来表示视角相关的颜色,即 \(Color(\mathbf{d}) = \sum c_{i,k} Y_k(\mathbf{d})\),其中 \(\mathbf{d}\) 是观察方向。

为了便于优化和学习,协方差矩阵 \(\boldsymbol{\Sigma}\) 被分解为缩放和旋转两部分:

\[\boldsymbol{\Sigma} = \mathbf{R} \mathbf{S} \mathbf{S}^T \mathbf{R}^T \]

  • \(\mathbf{S}\) 是一个对角矩阵,由缩放向量 \(\mathbf{s} = (s_x, s_y, s_z)\) 构成,代表高斯体在三个主轴上的伸缩。
  • \(\mathbf{R}\) 是一个旋转矩阵,通常由单位四元数 \(\mathbf{q}\) 转换而来,代表高斯体的朝向。
  • 优化技巧:直接优化 \(\mathbf{s}\)\(\mathbf{q}\) 比直接优化 \(\boldsymbol{\Sigma}\) 更稳定,且能保证 \(\boldsymbol{\Sigma}\) 始终是半正定的。

渲染时,需要将3D高斯体投影到相机成像平面上。根据透视投影的性质,3D高斯分布在经过仿射变换(包括透视投影的线性近似部分)后,仍然是一个2D高斯分布

假设相机的视图变换矩阵为 \(\mathbf{W}\)(World-to-View),投影矩阵为 \(\mathbf{J}\)(View-to-Screen的雅可比近似)。

  • 2D中心位置 \(\boldsymbol{\mu}'\):直接将3D中心 \(\boldsymbol{\mu}\) 通过相机投影得到。
  • 2D协方差矩阵 \(\boldsymbol{\Sigma}'\):通过变换矩阵 \(\mathbf{J}\mathbf{W}\) 对3D协方差进行变换:

    \[\boldsymbol{\Sigma}' = \mathbf{J} \mathbf{W} \boldsymbol{\Sigma} \mathbf{W}^T \mathbf{J}^T \]

这样,每个3D椭球在图像上就变成了一个2D椭圆,渲染过程就变成了经典的Alpha Blending(阿尔法混合)。

对于图像上的某个像素 \(\mathbf{u}\),其最终颜色 \(\mathbf{C}(\mathbf{u})\) 是由覆盖该像素的所有高斯体按深度顺序(从前到后)混合而成的:

\[\mathbf{C}(\mathbf{u}) = \sum_{i \in N} \mathbf{c}_i \alpha_i G_i'(\mathbf{u}) \prod_{j=1}^{i-1} (1 - \alpha_j G_j'(\mathbf{u})) \]

其中:

  • \(N\) 是按深度排序后的前 \(K\) 个高斯体(通常取前几个贡献最大的即可,因为高斯衰减很快)。
  • \(G_i'(\mathbf{u})\) 是第 \(i\) 个2D高斯在像素 \(\mathbf{u}\) 处的值(即上面提到的2D高斯函数)。
  • \(\alpha_i\) 是不透明度。
  • \(\mathbf{c}_i\) 是该高斯的颜色(由球谐函数计算得出)。
  • \(\prod (1 - \dots)\) 项表示前面所有高斯体未遮挡的部分(透射率)。

初始的高斯点云通常稀疏(由SfM生成),在训练过程中,算法会根据梯度动态调整高斯的数量和分布:

  1. 分裂(Split):如果一个高斯体的梯度过大(说明细节不够,需要更细的表示)或者尺寸过大,它会被分裂成两个更小的高斯体。
  2. 克隆(Clone):如果一个高斯体很小但梯度过大(说明这里需要更多点来覆盖),则复制一个相同的高斯体。
  3. 删除(Prune):如果不透明度 \(\alpha\) 变得非常小,或者高斯体变得非常大(覆盖全屏但贡献低),则将其删除。

这个过程周期性地进行,使得高斯点云能够自适应地拟合场景的几何细节(如边缘、纹理丰富区点密,平滑区点疏)。

posted @ 2026-03-16 18:53  kksk43  阅读(74)  评论(0)    收藏  举报