3D Gaussian Splatting 论文学习

embedded/2024/9/19 0:37:12/ 标签: 3dgs, 三维重建, 图形学

概述

目前比较常见的渲染方法大致可以分为2种:

  1. 将场景中的物体投影到渲染平面:传统的渲染管线就是这种方式,主要针对Mesh数据,可以将顶点直接投影成2D的形式,配合光栅化、深度测试、Alpha混合等就可以得到渲染的图像。
  2. 从相机到像素发出一条射线与场景物体交互去计算沿着射线的颜色积分:例如光线追踪,去计算光线和Mesh的光学行为(反射等)来得到像素的颜色值;或是体渲染,对于体数据或是隐式的场景表达(NeRF)通过采样的方式来计算一个光线上的离散的积分,得到最终的颜色。

隐式的场景表达因为其连续性天然具有可微性,比较适合放在优化框架中去使用,但是在渲染时由于需要随机采样,会浪费大量时间在无效的采样点上。3D高斯这个方法则结合了连续可微和投影后光栅化渲染的优势,实现了高质量的实时渲染效果。

接下来我以一些关键知识点为章节来进行总结:

3D高斯表示

3D高斯实际上就是点云+概率密度,使得场景离散化表示的同时对不存在顶点的空间有了连续的颜色变化。一个高斯球的数学形式可以表示为
G ( x ) = exp ⁡ ( − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ) G(x)=\exp{(-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu))} G(x)=exp(21(xμ)TΣ1(xμ))
其中 Σ \Sigma Σ是协方差矩阵, μ \mu μ是高斯球的重心坐标(均值)。论文中省略了高斯分布的归一化系数,这是因为我们并不需要得到严格的概率分布,只需要表达对空间的相对影响就行了。协方差矩阵 Σ \Sigma Σ是一个正定对称矩阵,是场景学习时的优化参数,如果直接优化一个3x3的矩阵很难满足高斯分布的性质,因此往往将其分解为旋转矩阵 R R R和缩放矩阵 S S S,即
Σ = R S S T R T \Sigma=RSS^TR^T Σ=RSSTRT
然后缩放用一个三维的向量表示,旋转用一个四元数表示。

以上的概率分布实际上定义了一个类似“椭球”的形状,用来表示某个高斯球对空间的影响程度,除此之外对每个高斯球还需要不透明度 α \alpha α和颜色信息。不透明度好理解,一个[0,1]的浮点数,深度排序后用来影响颜色的混合。而颜色信息,论文中用了四阶球谐函数(0, 1, 2, 3,每个颜色分量对应16个参数)来表示。因为我之前对球谐函数不太了解,所以这里简要总结一下球谐函数:

球谐函数(Spherical Harmonics),可以用来拟合球面函数 ρ = f ( θ , ϕ ) \rho=f(\theta,\phi) ρ=f(θ,ϕ)。实际上球谐函数就是一组基函数,怎么理解基函数呢?类似傅里叶展开的基函数为 { s i n ( p θ ) , c o s ( q θ ) } \{sin(p\theta),cos(q\theta)\} {sin(),cos()},用他们的线性组合可以拟合任意一个周期函数;也类似我们刚接触机器学习的欠拟合和过拟合时都会遇到的例子,用多项式去拟合数据点,也可以把 { 1 , x , x 2 , … , x k } \{1,x,x^2,\dots,x^k\} {1,x,x2,,xk}作为基函数,每个基函数前面乘的参数作为可学习的参数。

而用于拟合球面函数常用的基函数就是球谐函数
S m l ( θ , ϕ ) , − m ≤ l ≤ m S_m^l(\theta,\phi), \ -m\le l\le m Sml(θ,ϕ), mlm
它的具体形式就不展开了,需要再查吧,总之对于一个 m m m阶( m ≥ 0 m\ge0 m0)的球谐函数,它有 2 m + 1 2m+1 2m+1种变化。而对于一个任意的球面函数 f ( θ , ϕ ) f(\theta,\phi) f(θ,ϕ),我们用 k k k阶球谐函数去拟合的方式为
f ( θ , ϕ ) = ∑ m = 0 k ∑ l = − m m C m l S m l ( θ , ϕ ) f(\theta,\phi)=\sum_{m=0}^k \sum_{l=-m}^m C_m^l S_m^l(\theta,\phi) f(θ,ϕ)=m=0kl=mmCmlSml(θ,ϕ)
注意我这里的阶数是从0开始的。需要学习的参数是 C m l C_m^l Cml,总共有 ( k + 1 ) 2 (k+1)^2 (k+1)2个。

对于某个高斯球的颜色RGB,论文中每个分量用一个3阶(或者说是4阶,看从0还是1开始)球谐函数表示,总共48个参数,这样就可以根据任意视角 ( θ , ϕ ) (\theta,\phi) (θ,ϕ),查询这个高斯球的颜色了。

综上所述,每个3D高斯球有以下几个属性:

  • 位置: ( x , y , z ) (x,y,z) (x,y,z)
  • 缩放向量,四元数:表示高斯分布的协方差矩阵
  • 不透明度:opacity α \alpha α
  • 颜色:球谐函数拟合 C ( θ , ϕ ) C(\theta,\phi) C(θ,ϕ)

图片渲染

假设所有的高斯球已经训练好,要怎么渲染成2D的图像呢?前面也讲到过,像NeRF是发射光线,然后沿着光线进行采样对颜色做离散积分,如果套用到3D高斯的话,就要在光线路径上采样,然后计算所有(或者附近)的高斯球在该采样点的颜色。然而论文方法名称里叫“Splatting”,顾名思义就是“溅射”,或者说是“抛雪球”,比较形象的解释了高斯球的渲染方式:直接投影到2D。

给定一个视图变换(世界坐标到相机坐标)矩阵 W W W,相机坐标下某个高斯球的协方差矩阵为
Σ ′ = J W Σ W T J T \Sigma'=JW\Sigma W^TJ^T Σ=JWΣWTJT
其中 J J J为投影变换的仿射近似的雅各比矩阵,假设投影变换 x ′ = p ( x ) x'=p(x) x=p(x),那么 J = ∂ p ∂ μ J=\frac{\partial p}{\partial\mu} J=μp ,投影变换就可以近似为 x ′ = p ( μ ) + J ( x − μ ) x'=p(\mu)+J(x-\mu) x=p(μ)+J(xμ) 。其实就是把一个非线性的投影变换近似成一个线性变换,使得3D高斯投影后还是一个2D高斯。

至此,图片的渲染就可以对每个像素点,按照距离(深度)对所有高斯球排序,然后根据深度和不透明度以及二维高斯分布计算累加的颜色。论文还提出了一种加速方式,就是将图片分为16x16的小块,每一块按照一定置信度找到受影响的所有高斯球进行排序,后续就不再对每个像素单独排序了,并且每个小块只计算被影响的高斯球的颜色叠加。这样GPU上的每个Block处理一个小块,共享内存,每个Thread再处理一个像素点,光栅化过程就会非常非常快。

训练策略

训练流程如下图所示

image-20240910144820202

先用SFM(Structure From Motion,例如Colmap)将多视角图片转为点云,然后进行高斯球的初始化,然后再进行迭代训练以及进行高斯球密度的调整。

高斯球密度调整策略一般每过一定迭代次数调整一次,大致类型如下:

  1. 对于不透明度低于一定阈值的高斯球,直接删除(说明是空的,对应区域没有物体);
  2. 对于位置梯度(也就是对高斯球中心坐标那三个参数求导)过大的区域,可能有两种情况:
    1. 欠拟合:说明高斯球无法很好的填充周围的空白区域,于是克隆一个新的相同的高斯球;
    2. 过拟合,高斯球填满了周围的区域,还溢出了很多,于是分割成两个更小的高斯球

总结

相较于NeRF,3D高斯确实在保证质量的情况下,速度快很多,基本能够达到实时的渲染,并且训练时间也不长(半小时左右)。不过3D高斯是显式的表示,占用的内存和显存更高,保存场景时占用的空间比NeRF高了2个数量级。


http://www.ppmy.cn/embedded/111193.html

相关文章

「iOS」折叠cell

iOS学习 前言简单的折叠cell效果原理 稍作修改总结 前言 在暑期仿写中,3G share项目里我们简单的使用了折叠cell。现在写一篇博客来总结该方法。 简单的折叠cell 效果 先看效果: 原理 将cell的高度设置为一个单元格的高度。创建一个按钮&#xff0…

云服务器 卸载mysql5并安装mysql8(图文)

目录 1. 卸载2. ubuntu安装3. Bug彩蛋3.1 mysql5配置3.2 跳出密码验证4. 补充centos1. 卸载 在云服务器上卸载 MySQL 5 并安装 MySQL 8 的过程涉及几个步骤,包括 MySQL 版本的移除、系统清理、安装 MySQL 8,以及配置数据库 1.检查 MySQL 版本:mysql --version 2. 停止 My…

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息,然后展示在页面上。 效果展示 首次发送需要…

docker入门安装及使用

docker概述 docker是一种容器技术,它提供了标准的应用镜像(包含应用和应用多需要的依赖),因此,我们可以非常轻松的在docker中安装应用,安装好的应用相当于一个独立的容器 如下图所示,为docker中…

phpmyadmin报错mysqli::real_connect(): (HY000/1045): Access denied for user ‘

问题分析 这是因为本身还安装了MySQL,导致发生冲突,只需要找到自己安装的进行关闭即可 方法 在任务管理器(快捷键:ctrlaltdelete)-服务中,找到对应的MySQL进行关闭

使用多进程或多线程进行requests请求数据并比较score

要在Python中使用多进程或多线程并发地向多个接口请求数据,并且每个接口返回一个包含score字段的字典,可以使用requests库结合concurrent.futures模块来实现。这里将提供两种实现方式:一种使用多线程,另一种使用多进程。 1. 使用多…

柯桥外语学习生活日语之与台风有关的日语表达

与台风有关的日语表达: 台風が近づいている (たいふうがちかづいている) - 台风正在靠近 台風が上陸する (たいふうがじょうりくする) - 台风登陆 台風の進路 (たいふうのしんろ) - 台风的路径 強い台風 (つよいたいふう) - 强烈的台风 台風の目 (たいふうのめ…

HP电脑如何启动硬件检测

许多人都在使用HP电脑,但是当出现问题时候,不知道该如何测试,本文来分享一下,如何在电脑能开机但是有问题时进行检测。 使用F2键进行组件测试 步骤:开机后不停敲击键盘上【F2】的按键,进入BIOS设置界面&am…

VSCode中latex文件(Misplaced alignment tab character .LaTeX

Misplaced alignment tab character &.LaTeX 先给出参考文章1 Misplaced alignment tab character &.LaTeX 把bib文件中的 &改为 and 。删除原有的bbl文件、重新运行 选择这个运行 这个错误在overleaf上并没有遇到、在vscode上遇到了 方法二就是把 &改为…

类组件化websocket的方法(心跳机制)

/*** WebSocket统一管理*/ export class WebSocketClient {constructor(url) {if (!url) {throw new Error("WebSocket URL is required.");}this.url url;this.websocket null;this.listeners {};this.heartbeatInterval 30000; // 心跳检测间隔(毫秒…

第十一周:机器学习

第十一周周报 摘要Abstract机器学习1. 注意力机制(下)1.1 multi-head self-attention(多头注意力机制)1.2 Positional Encoding(位置编码)1.3 truncated self attention(截断式注意力机制&#…

初阶数据结构【TOP】-6. 队列的实现

文章目录 前言一、什么是队列?二、队列的选择二、队列的实现总结 前言 本篇文章笔者将会对 “ 队列 ” 进行细致的讲解 , 从队列的介绍 - 队列的选择 - 队列的实现 , 逐一进行。 一、什么是队列? ★ 概念:只允许在一…

工厂模式(二):工厂方法模式

一、概念 工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。从而使得系统更加灵活。客户端可以通过调用工厂方法来创建所需的产品,而不必…

ICLR2024: 大视觉语言模型中对象幻觉的分析和缓解

https://arxiv.org/pdf/2310.00754 https://github.com/YiyangZhou/LURE 背景 对象幻觉:生成包含图像中实际不存在的对象的描述 早期的工作试图通过跨不同模式执行细粒度对齐(Biten et al.,2022)或通过数据增强减少对象共现模…

sqli-labs靶场自动化利用工具——第13关

文章目录 概要整体架构流程技术细节执行效果小结 概要 Sqli-Labs靶场对于网安专业的学生或正在学习网安的朋友来说并不陌生,或者说已经很熟悉。那有没有朋友想过自己开发一个测试脚本能实现自动化化测试sqli-labs呢?可能有些人会说不是有sqlmap&#…

android.database.sqlite.SQLiteException: no such table

android.database.sqlite.SQLiteException: no such table 这个异常通常表明你的 SQLite 数据库中不存在你试图访问的表。这种情况可能由几个原因引起: 数据库表未创建:你可能没有在应用的数据库初始化代码中创建这个表。确保在你的数据库帮助类&#xf…

[项目][WebServer][项目介绍及知识铺垫][上]详细讲解

目录 1.何为WWW?2.HTTP分层1.整体2.细节3.DNS?4.协议之间是如何协同运作的? 3.Http相关概念1.特点2.URI && URL && URN3.HTTP URL格式 1.何为WWW? WWW是环球信息网的缩写,常简称为Web分为Web客户端和Web服务器程序,WWW可…

SpringMvc 完整上传文件流程(Ajax请求)头像,图片上传

1、config包下的操作 1.1、创建MyWebApplicationInit类 如何创建第一个SpringMvc步骤 以配置类的形式代替xml文件(点击链接查看) 1.2、设置文件大小(自定义) 1.3、创建SpringMvcConfig类 并实现 WebMvcConfigurer接口 EnableW…

LabVIEW如何确保采集卡稳定运行

在LabVIEW开发中,如何确保硬件采集卡稳定运行,特别是长期采集电压信号,是系统稳定性的重要考虑因素。用户在使用采集卡时,可能需要频繁进行开始、停止和重新采集的操作,这对硬件和软件提出了高要求。下面介绍实现长期稳…

qt --如何获取本地联网的网口mac地址

单独的获取某一个网卡的mac地址 在代码里 可能出现意料之外的bug 如果你本地的网卡较多 QList< QString > ABC::getMac() {QList< QNetworkInterface > nets QNetworkInterface::allInterfaces(); // 获取所有网络接口列表int nCnt nets.count();QList< QStr…