3D Rendering

A Survey on 3D Gaussian Splatting
3D Gaussian splatting (3D GS) has recently emerged as a transformative technique in the explicit radiance field and computer graphics landscape. This innovative approach, characterized by the...
https://arxiv.org/abs/2401.03890

Background


Overview

  1. 辐射场:辐射场是三维空间中光分布的表示,它捕捉光如何与环境中的表面和材料相互作用。从数学上讲,辐射场可以描述为函数,其中将空间中的一个点和由球面坐标指定的方向映射到非负辐射值。辐射场可以通过隐式或显式表示进行封装,每种表示都具有特定的场景表示和渲染优势。
  1. 隐式辐射场:隐式辐射场表示场景中的光分布,而不明确定义场景的几何体。在深度学习时代,它经常使用神经网络来学习连续的体积场景表示。最突出的例子是NeRF。在NeRF中,MLP网络用于将一组空间坐标和观看方向映射到颜色和密度值。任何点的辐射度都不是明确存储的,而是通过查询神经网络实时计算的。因此,函数可以写成:

这种格式允许对复杂场景进行可微分和紧凑的表示,尽管由于体积光线行进,渲染过程中的计算负载往往很高。

  1. 显式辐射场:相反,显式辐射场直接表示离散空间结构中的光分布,例如体素网格或点集。该结构中的每个元素存储其在空间中的相应位置的辐射信息。这种方法允许更直接且通常更快地访问辐射数据,但代价是更高的内存使用率和潜在的更低分辨率。显式辐射场表示的一般形式可以写成:

其中DataStructure可以是网格或点云,是基于观看方向修改辐射的函数。

  1. 两全其美的3D Gaussian Splatting:3D GS表示从隐式辐射场到显式辐射场的转变。它通过利用3D高斯作为灵活高效的表示,利用了这两种方法的优势。这些高斯系数经过优化,可以准确地表示场景,结合了基于神经网络的优化和显式结构化数据存储的优点。这种混合方法旨在通过更快的训练和实时性能实现高质量渲染,特别是对于复杂的场景和高分辨率输出。3D高斯表示公式化为:

传统方法

早期的技术基于光场生成逼真的图像,后期

通过从图像序列估计3D结构进一步推进了这一领域。

典型的神经场算法在视觉计算中如下:

NeRF-Based, 2020

一文详解 | 你还没了解NeRF 神经辐射场吗?
微信号 cv3derNews
https://mp.weixin.qq.com/s?__biz=MzkyMTUwMTU5Mg==&mid=2247484754&idx=1&sn=b95863155ecf7a7537cd45836598925e&chksm=c183efa5f6f466b3c63d2a4d0dbaca076ac1148c76c8cab58365471823c06339c0c11bed9496&token=752429925&lang=zh_CN#rd

3D Gaussian Splatting 抛雪球

3D Gaussian Splatting中的数学推导
此文记录个人学习过程,如有错误欢迎私信交流,十分感谢!(第一次在知乎发blog,紧张。) 3D Gaussian Splatting,简记为3DGS,是一种很有希望的场景表达方式。我在YouTube冲浪相关视频时,看到了这样一段评论: …
https://zhuanlan.zhihu.com/p/666465701
一文带你入门 3D Gaussian Splatting
强烈去看 b 站 up 主中恩实验室的系列视频! Siggraph 2023 Best Paper!1. 引言1.1 任务文章涉及到的任务是三维重建+渲染。 文章提出了一种新方法实现了辐射场的实时渲染,能够在较少的训练时间中,实现SOTA级别…
https://zhuanlan.zhihu.com/p/680669616
开始弃用NeRF?为什么Gaussian Splatting在自动驾驶场景如此受欢迎?
本文经自动驾驶之心公众号授权转载,转载请联系出处。写在前面&笔者的个人理解三维 Gaussian splatting(3DGS)是近年来在显式辐射场和计算机图形学领域出现的一种变革性技术。这种创新方法的特点是使用了数百万个3D高斯,这与神经辐射场(NeRF)方法有很大的不同,后者主要使用隐式的基于坐标的模型将空间坐标映射到像素值..
https://www.gfkjgy.com/cms/show-3671.html

Data

数据集包含,

Preprocess

Transformation

[xs ys 1]T=HisHciHwc[X Y Z 1]T[x^s\ y^s\ 1]^T=H^s_iH^i_cH^c_w[X\ Y\ Z\ 1]^T
xi=fxc/zcyi=fyc/zczc[xiyi1]=[f0000f000010][xcyczc1]x_i=fx_c/z_c\\ y_i=fy_c/z_c\\ z_c\begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}= \begin{bmatrix} f & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} x_c \\ y_c \\ z_c \\ 1 \end{bmatrix}
(四十)通俗易懂理解——相机坐标转换
首先要弄清相机坐标的转换关系。一、世界坐标系(world coordinate),也称为测量坐标系,是一个三维直角坐标系,以其为基准可以描述相机和待测物体的空间位置。世界坐标系的位置可以根据实际情况自由确定。 坐标…
https://zhuanlan.zhihu.com/p/90295867
最本质的相机内参intrinsics与外参extrinsics分析,从建模,推导到求解_intrinsic camera-CSDN博客
文章浏览阅读6.1k次,点赞17次,收藏38次。本文从最本质的原理出发,对相机的外参和内参进行了描述。从不同坐标系的建模,到3D到2D的投影矩阵分析,到矩阵变换的求解。全面的分析和描述了相机参数的原理。camera extrinsics and intrinsics。_intrinsic camera
https://blog.csdn.net/qq_32998593/article/details/105628305

SfM initialization, Structure from Motion

可以直接调用 COLMAP 库来完成这一步,当无法获得点云时,可以使用随机初始化来代替,但可能会降低最终的重建质量和收敛速度。SfM 初始化点云过程的主要步骤如下:

Model parameter

每个高斯椭圆面的参数,包括

Projection

将点云投影到对应的成像平面,获得投影后的新不透明度α^\hat\alpha,以及椭球投影到平面后的形状^\hat\sum,用于光栅化渲染

W=[RX003T1]c=(xc,yc,zc)Ts=(xs,ys,zs)T^=JWWTJTs=ϕ(c)=(xc/zc,yc/zc,(xc,yc,zc))TJ=(xsxcxsycxszcysxcysycyszczsxczsyczszc)=(1/zc0xc/zc201/zcyc/zc2xc/cyc/czc/c)α^=α×exp[0.5(VsV0)T^1(VsV0)]Vs=(xs,ys)T, V0=(x0,y0)TW=\begin{bmatrix} R & X_0 \\ 0_3^T & 1 \end{bmatrix}\\ c=(x_c,y_c,z_c)^T\\ s=(x_s,y_s,z_s)^T\\ \hat\sum=JW\sum W^TJ^T\\ s=\phi(c)=(x_c/z_c, y_c/z_c, ||(x_c,y_c,z_c)||)^T\\ J=\begin{pmatrix} \frac {\partial x_s}{\partial x_c} & \frac {\partial x_s}{\partial y_c} & \frac {\partial x_s}{\partial z_c} \\ \frac {\partial y_s}{\partial x_c} & \frac {\partial y_s}{\partial y_c} & \frac {\partial y_s}{\partial z_c} \\ \frac {\partial z_s}{\partial x_c} & \frac {\partial z_s}{\partial y_c} & \frac {\partial z_s}{\partial z_c} \end{pmatrix}=\begin{pmatrix} 1/z_c & 0 & -x_c/z_c^2 \\ 0 & 1/z_c & -y_c/z_c^2 \\ x_c/||c|| & y_c/||c|| & z_c/||c|| \end{pmatrix} \\ \hat\alpha=\alpha\times exp[-0.5\cdot(V_s-V_0)^T\hat\sum^{-1}(V_s-V_0)]\\ V_s=(x_s,y_s)^T,\ V_0=(x_0,y_0)^T

Rasterization

Tile

通过分块的方式加速渲染,而不是检索每个图像空间的像素级别

排序 & alpha blending

raster_settings = GaussianRasterizationSettings(
    image_height=int(viewpoint_camera.image_height),
    image_width=int(viewpoint_camera.image_width),
    tanfovx=tanfovx,
    tanfovy=tanfovy,
    bg=bg_color,
    scale_modifier=scaling_modifier,
    viewmatrix=viewpoint_camera.world_view_transform,
    projmatrix=viewpoint_camera.full_proj_transform,
    sh_degree=pc.active_sh_degree,
    campos=viewpoint_camera.camera_center,
    prefiltered=False,
    debug=pipe.debug
)  # 每张图片分别渲染

self._xyz = nn.Parameter(torch.tensor(xyz, dtype=torch.float, device="cuda").requires_grad_(True))
self._features_dc = nn.Parameter(torch.tensor(features_dc, dtype=torch.float, device="cuda").transpose(1, 2).contiguous().requires_grad_(True))
self._features_rest = nn.Parameter(torch.tensor(features_extra, dtype=torch.float, device="cuda").transpose(1, 2).contiguous().requires_grad_(True))
self._opacity = nn.Parameter(torch.tensor(opacities, dtype=torch.float, device="cuda").requires_grad_(True))
self._scaling = nn.Parameter(torch.tensor(scales, dtype=torch.float, device="cuda").requires_grad_(True))
self._rotation = nn.Parameter(torch.tensor(rots, dtype=torch.float, device="cuda").requires_grad_(True))

(超详细!)计算机图形学 入门篇 1. 变换矩阵
本节内容主要是图像变换所对应的矩阵操作,图像的变换操作都可以视作其对应点与变换矩阵相乘所得到的变换结果。课程资料来源于《Fundamentals of Computer Graphics》以及闫老师的GAMES 101课程 GAMES101: 现代计…
https://zhuanlan.zhihu.com/p/448115462

自适应密度控制

Loss

Combination of L1 loss (absolute of MAE) and D-SSIM(structural similarity index measure) loss,结构相似性

L=(1λ)L1+λLSSIMλ=0.2L=(1-\lambda)L_1+\lambda L_{SSIM}\\ \\ \lambda=0.2
	def _ssim(img1, img2, window, window_size, channel, size_average=True) : # gaussian kernel window 
    mu1 = F.conv2d(img1, window, padding=window_size // 2, groups=channel)
    mu2 = F.conv2d(img2, window, padding=window_size // 2, groups=channel)

    mu1_sq = mu1.pow(2)
    mu2_sq = mu2.pow(2)
    mu1_mu2 = mu1 * mu2

    sigma1_sq = F.conv2d(img1 * img1, window, padding=window_size // 2, groups=channel) - mu1_sq
    sigma2_sq = F.conv2d(img2 * img2, window, padding=window_size // 2, groups=channel) - mu2_sq
    sigma12 = F.conv2d(img1 * img2, window, padding=window_size // 2, groups=channel) - mu1_mu2

    C1 = 0.01 ** 2
    C2 = 0.03 ** 2

    ssim_map = ((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * (sigma1_sq + sigma2_sq + C2))

    if size_average:
        return ssim_map.mean()
    else:
        return ssim_map.mean(1).mean(1).mean(1)
SSIM (Structure Similarity Index Measure) 结构衡量指标+代码
SSIM (Structure Similarity Index Measure) 结构衡量指标+代码介绍结构相似指标可以衡量图片的失真程度,也可以衡量两张图片的相似程度。与MSE和PSNR衡量绝对误差不同,SSIM是感知模型,即更符合人眼的直观感受。…
https://zhuanlan.zhihu.com/p/399215180

Optimizer

train: Adam

Evaluation: EMA

一句话总结权重滑动平均(Exponential Moving Average)就是:Copy一份模型所有权重(记为Weights)的备份(记为EMA_weights),训练过程中每次更新权重时同时也对EMA_weights进行滑动平均更新,训练阶段结束后用EMA_weights替换模型权重进行预测。

具体地,EMA的超参decay一般设为接近1的数,从而保证每次EMA_weights的更新都很稳定。每batch更新流程为:

Weights=Weights+LR*Grad; (模型正常的梯度下降)

EMA_weights=EMA_weights*decay+(1-decay)*Weights; (根据新weight更新EMA_weights)

应用领域