- 论文名称《NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis》
- arXiv:2003.08934
- 提出了一种方法,该方法通过使用一组稀疏的输入视图优化底层连续体积场景函数,从而获得用于合成复杂场景的新颖视图的最先进结果
NeRF 简介
目前 3D 画面绘制 比较流行的方式有 mesh model(网格模型) 和 点云,NeRF 就是提出一个新的方式去对 3D 场景进行表达。
NeRF(Neural Radiance Fields神经辐射场)将隐式表达推上了一个新的高度,仅用2D的posed images作为监督,即可表示复杂的三维场景。
它要处理的任务是新视角合成。我们用一个直观的表述方式来理解它的作用,如下图所示,如果我们需要对图中的挖掘机进行新视角合成,首先我们会围绕挖掘机采集不同角度的图像,之后计算每个采集角度的相机位姿,将采集的图像序列以及它们对应的位姿送入到NeRF,就可以合成一些新的视角。
也就是我们从空间中任意位置来看这个挖掘机,看到的图像应该是什么样的,NeRF可以合成出来。
- 比如某个2D图片(像素点组成),每个像素点的数值是固定的,我们将其放大,会发现其变模糊。
- 有没有什么办法让图片放大之后不变模糊呢?
- 矢量图,无论怎么放大,显示依旧很清晰(一个专门做矢量图的软件: Adobe Illustrator)
- 例如一个图像为正方形的矢量图,其放大之后不会变模糊,为什么呢?有什么方法?
- 用边的函数去表达一个几何体,这个在计算机有个专有名词 implicit(隐式表达)
- 其是用函数形式表示一个几何体
- 同样输入 3d 点,通过训练好的神经网络,能够输出该3D点在2d平面上投影出来的像素值,这就是一个隐式表达,这就是 NeRF 做的工作。
NeRF 原理核心解读
原理(公式)
NeRF算法使用全连接(非卷积)深度网络表示场景,其输入是单个连续的 5D 坐标(空间位置 (x, y, z) 和观察方向 (θ, φ)),其输出是该空间位置的体积密度和视点相关的发射辐射率。
通过沿相机光线查询 5D 坐标来合成视图,并使用经典的体积渲染技术将输出颜色和密度投影到图像中。因为体绘制是自然可微的,所以优化我们的表示所需的唯一输入是一组具有已知相机姿势的图像。描述了如何有效地优化神经辐射场以渲染具有复杂几何形状和外观的场景的逼真新视图,并展示了优于先前神经渲染和视图合成工作的结果。
- 输入:5D - Position(位置) + Direction(方向)
- (x, y, z, θ, φ),三维坐标点 + 射线
- 确定一条线:两点确定一个线
- 明明欧拉角(航空翻滚角)有三个变量,为什么这里只有两个变量就可以表示方向了?
- 因为对于一个射线(射线旋转没有意义),其roll方向(箭头指的方向)的旋转对其的方向是没有影响的。。
- 物理上的意义:怎么通过射线去把颜色算出来呢?这个射线其实就是一条光线,从一个点发出无数根光线,沿线会击中空间中的很多粒子,没有东西的地方就是透明的,有东西的地方就是一个刚体,就会其把后面的物体遮挡。怎么算的呢?最开始就是 Volume Rendering体素渲染, 这种思想最开始用于计算机视觉里面的烟雾的渲染,是有不透明度的
- 怎么呈现某个像素点的值到底是多少呢? 把射线击中的粒子全部去积分起来,把每个粒子的颜色还有透明度去积分算起来,就是这条射线最终呈现在图片上的像素点的值,如果是整条射线去积分的话,因为有无数个粒子,是很不现实的,后面会通过采样的方式在光线上采样,把采到的样本点的颜色和密度值,把积分换成离散型的加权求和,最终得到其呈现在 2D 图像上的 RGB值。
C(r)=∫tntfT(t)σ(r(t))c(r(t),d)dt, where T(t)=exp(−∫tntσ(r(s))ds)tn,tf:近点(近界),远点(原界),项目网页中的数据集会提供最近点和最远点?t:tn和tf之间的某个t值r(t):r就是ray射线光线的意思,r(t)=o+td,原点+方向点σ(r(t)):射线上某一点t的密度值c(r(t),d):射线上某一点t的颜色值d:射线方向T(t):权重;对射线上tn到t的密度值的积分,越远说明越大,但是对其负值取对数,说明越远对我们的最终成像的贡献值越低,权重也就越低,透明度越低,说明密度积分越大,t后面的对我们成像的贡献值也越低,也就得到了一个关于距离和透明度对最终成像的一个权重函数最终就是对射线上从近界tn到原界tf之间的所有点的密度值∗颜色值∗权重的积分\begin{aligned} C(\mathbf{r})&=\int_{t_{n}}^{t_{f}} T(t) \sigma(\mathbf{r}(t)) \mathbf{c}(\mathbf{r}(t), \mathbf{d}) d t, \text { where } T(t)=\exp \left(-\int_{t_{n}}^{t} \sigma(\mathbf{r}(s)) d s\right) \\ \\ & t_n,t_f:近点(近界),远点(原界),项目网页中的数据集会提供最近点和最远点? \\ & t:t_n和t_f 之间的某个 t 值\\ & \mathbf{r}(t):r就是ray射线光线的意思,\mathbf{r}(t) = \mathbf{o}+t \mathbf{d},原点+方向点 \\ & \sigma(\mathbf{r}(t)):射线上某一点t的密度值 \\ & \mathbf{c}(\mathbf{r}(t), \mathbf{d}):射线上某一点t的颜色值\\ & d:射线方向 \\ & T(t):权重; 对射线上t_n到t的密度值的积分,越远说明越大,但是对其负值取对数,\\ & \qquad 说明越远对我们的最终成像的贡献值越低,权重也就越低,\\ & \qquad 透明度越低,说明密度积分越大,t后面的对我们成像的贡献值也越低,\\ & \qquad 也就得到了一个关于距离和透明度对最终成像的一个权重函数 \\ \\ & 最终就是对射线上从近界t_n到原界t_f之间的所有点的密度值*颜色值*权重的积分\\ \end{aligned} C(r)=∫tntfT(t)σ(r(t))c(r(t),d)dt, where T(t)=exp(−∫tntσ(r(s))ds)tn,tf:近点(近界),远点(原界),项目网页中的数据集会提供最近点和最远点?t:tn和tf之间的某个t值r(t):r就是ray射线光线的意思,r(t)=o+td,原点+方向点σ(r(t)):射线上某一点t的密度值c(r(t),d):射线上某一点t的颜色值d:射线方向T(t):权重;对射线上tn到t的密度值的积分,越远说明越大,但是对其负值取对数,说明越远对我们的最终成像的贡献值越低,权重也就越低,透明度越低,说明密度积分越大,t后面的对我们成像的贡献值也越低,也就得到了一个关于距离和透明度对最终成像的一个权重函数最终就是对射线上从近界tn到原界tf之间的所有点的密度值∗颜色值∗权重的积分
- 上面这个就是整个渲染的初始公式。
- 密度函数就先当作透明度就好了
- 权重 T(t):比如射线穿过去一个烟雾,我们还可以模糊的看到烟雾后面的东西,但是如果是一堵墙,后面的东西全部都遮挡掉了,我们是看不到的。
- 越接近人眼的、并且透明度越低的 对我们最终成像的贡献越大,越往后面的对我们成像的贡献就越小
C^(r)=∑i=1NTi(1−exp(−σiδi))ci, where Ti=exp(−∑j=1i−1σjδj)\hat{C}(\mathbf{r})=\sum_{i=1}^{N} T_{i}\left(1-\exp \left(-\sigma_{i} \delta_{i}\right)\right) \mathbf{c}_{i}, \text { where } T_{i}=\exp \left(-\sum_{j=1}^{i-1} \sigma_{j} \delta_{j}\right)C^(r)=i=1∑NTi(1−exp(−σiδi))ci, where Ti=exp(−j=1∑i−1σjδj)
如果对射线上全部粒子都积分,是很困难的,因此需要进行分层采样,上面就是离散化之后的函数.
分层采样:将 [tn, tf ] 划分为 N 个均匀分布的箱子,然后从每个箱子内随机均匀地抽取一个样本:
ti∼U[tn+i−1N(tf−tn),tn+iN(tf−tn)]t_{i} \sim \mathcal{U}\left[t_{n}+\frac{i-1}{N}\left(t_{f}-t_{n}\right), t_{n}+\frac{i}{N}\left(t_{f}-t_{n}\right)\right]ti∼U[tn+Ni−1(tf−tn),tn+Ni(tf−tn)]
优化神经辐射场
- Positional encoding 位置编码,在神经网络训练里面很常用的操作,用于提特征,让泛化性能更好,有进行试验,如下:
- Hierarchical volume sampling 分层体积采样
- 我们在沿每个摄像机射线的 N 个查询点处密集评估神经辐射场网络的渲染策略效率低下:对渲染图像没有贡献的自由空间和遮挡区域仍然重复采样。通过按比例分配样本以使其对最终渲染的预期效果来提高渲染效率。
NeRF模型结构
MLP(多层感知机模型) – 基于最初很常用的 BP 神经网络
- 这是一个10层的线性神经网络
- 绿色方块: 表示使用位置编码
- 分别在最开始和第5层输入一个3D坐标点的位置编码(3D点编码成60特征的向量)
- 第9层输出一个密度值
- 同时在第9层输入一个射线方向的位置编码(射线方向d编码成24特征的特征向量)
- 最后输出RGB值
- 思想: 密度只跟位置相关,跟我们那个方向去看没关系;
- 颜色跟我们哪个方向去看有关系,因为颜色会根据光线改变
- 看的这个视角的起点位置在输出完密度之后,才会将射线方向加入神经网络中
打个广告(嘿嘿)
- 科研之路,论文为峰。英文不佳,阅读难通?别慌!我们提供精准论文翻译,助您跨越语言障碍,深入理解文献精要。最低可至 0.1 元/篇,超高性价比之选。(目前仅限 arXiv 网址上收录的论文哦!不过关于 AI的论文基本都收录在arXiv上哦!)
- 如有需要,欢迎添加微信:thesisTrans,开启便捷科研之旅!
- 微信二维码:
- 效果展示: