目录
NeRF简介
课程 教程
代码实践
商业应用
NeRF简介
NeRF(神经辐射场)是当前最为火热的研究领域之一(基于NeRF的三维视觉年度进展报告),效果非常惊艳,它要解决的问题就是给定一些拍摄的图,如何生成新的视角下的图. 不同于传统的三维重建方法把场景表示为点云、网格、体素等显式的表达,它独辟蹊径,将场景建模成一个连续的5D辐射场隐式存储在神经网络中,只需输入稀疏的多角度带pose的图像训练得到一个神经辐射场模型,根据这个模型可以渲染出任意视角下的清晰的照片。通俗来讲就是构造一个隐式的渲染流程,其输入是某个视角下发射的光线的位置o,方向d以及对应的坐标(x,y,z),送入神经辐射场Fθ得到体密度和颜色,最后再通过体渲染得到最终的图像。NeRF最先是应用在新视点合成方向,由于其超强的隐式表达三维信息的能力后续在三维重建方向迅速发展起来. 论文翻译 NeRF 论文主要点细致介绍
NeRF提出了一种从一组输入图像中优化连续5D神经辐射场的表示(任何连续位置的体积密度和视角相关颜色)的方法。使用体渲染技术沿光线累积此场景表示的采样点信息,以遍从任何视角渲染场景。在这里可视化了在半球区域上随机捕获的合成鼓(Synthetic Drums)场景的100个输入视图集,并展示了从优化后的NeRF表示中渲染的两个新视角下的图
NeRF三问
1. NeRF效果为什么那么好,它解决了现有三维表达的哪些问题?
2. NeRF为什么那么慢?如何加速?
3. 为什么没看到其大规模商业应用?什么限制了它的普及?
1的解答: NeRF学习笔记 基于神经表示的三维重建建模
视角合成方法通常使用一个中间3D场景表征作为中介来生成高质量的虚拟视角,如何对这个中间3D场景进行表征,分为了“显示表示“和”隐式表示“,然后再对这个中间3D场景进行渲染,生成照片级的视角。“显示表示”3D场景包括网格,点云,体素等,它能够对场景进行显式建模,但是因为其是离散表示的,导致了不够精细化会造成重叠等伪影,更重要的是它存储的三维场景表达信息数据量极大,对内存的消耗限制了高分辨率场景的应用。”隐式表示“3D场景通常用一个函数来描述场景几何,可以理解为将复杂的三维场景表达信息存储在函数的参数中。因为往往是学习一种3D场景的描述函数,因此在表达大分辨率场景的时候它的参数量相对于“显示表示”是较少的,并且”隐式表示“函数是种连续化的表达,对于场景的表达会更为精细。NeRF做到了利用”隐式表示“实现了照片级的视角合成效果,它选择了Volume作为中间3D场景表征,然后再通过Volume rendering实现了特定视角照片合成效果。可以说NeRF实现了从离散的照片集中学习出了一种隐式的Volume表达,然后在某个特定视角,利用该隐式Volume表达和体渲染得到该视角下的照片。
显式是离散的表达,不能精细化,导致重叠等伪影,耗费内存,限制了在高分辨率场景的应用。
隐式是连续的表达,能够适用于大分辨率的场景,而且不需要3D信号进行监督。 在NeRF之前,它的缺点是无法生成照片集的虚拟视角。eg:occupancy field、signed distance function(SDF)
2的解答 基于神经渲染的商品三维建模技术
NeRF速度慢的原因有几个方面,第一,有效像素少,生成得到的2D图像有效像素不到1/3,能够快速得到有效像素可以提升推理速度。第二,有效体素少,采样192个点,其中只有表面附近的点密度σ比较大,其他的点没必要进行推理。第三,网络推理速度慢,需要12层全连接网络推理,才能得到1个体素的颜色和密度,能优化这个性能也可以大大加快推理速度。通过空间换时间的方式,可以进行优化,包括FastNeRF、PlenOctree等方法,但是仅仅是单纯的记住NeRF输出结果,会使得存储空间过大,达到200M~1G的大小,这样的大的模型也是没法实用的。
3的解答 NeRF 背景、改进、应用与发展
NeRF目前还没有比较成功的商业化的应用,论文中的出色效果许多无法在现实中落地。技术如果不能落地,就会变成空中楼阁。NeRF还存在训练速度慢、渲染速度慢、只能用于静态场景、泛化性能差、需要大量视角、难以与传统渲染管线融合等问题,这里我们没有办法说明,隐式神经表示是未来的视觉领域的新钥匙,它的意义还需要时间和实验来证明。但是它所呈现了那一个个惊艳的demo,确实是我们对视觉和图形学最理想的追求。
第9行是NeRF完整的模型做为参考基线,第一行是去除了位置编码、视角相关性和分层采样后的最小版本,2-4行是从完整模型分别去除位置编码、视角相关性和分层采样的结果,不难看出位置编码和视角相关性最为重要,分层采样也有一定的收益。5-6行展示了输入图片减少下的性能,请注意只有25张的结果依然超过了其他最好的方法。7-8行展示了位置编码L选择的影响,如果只使用5会降低性能,但是从10到15并不能提升性能,一旦2的L次方超过图中最大的频率(在我们的数据中大约是1024)再增大L的收益是有限的
针对NeRF 根本性缺陷 的改进
Mip-NeRF
NeRF只在相机位置固定、改变观察方向的视角生成上表现较好。当拉近、拉远时图像会产生锯齿以及模糊。NeRF对每一个像素只发射一条光线,如果多发射几条光线、提高采样率,在一定程度上能够解决锯齿化的问题,但这样的方法大大增加了计算量,效率低下。于是Mip-NeRF提出了用圆锥体取代光线的方案。
BARF
NeRF的依赖于准确的先验姿态,而BARF在没有非常准确的位姿情况下,仍然可以取得非常不错的结果
NeRF系列工作个人总结
为什么要引入 Positional Encoding,即人为地引入高频信息,是因为作者发现 MLP 更倾向于学习低频信号,这点在 [2, 3] 中均有理论性的说明,同时 [4] 还给出了 Positional Encoding 能凑效的推导。 就我个人而言,MLP 通常由多层的参数矩阵组成,在计算即前传的过程中,还存在着大量的非线性激活,这使得 MLP 具有非常良好的插值性质,能够输出足够平滑的结果(我们老师将之称为 Deep Prior,我个人理解是属于 MLP 的 inductive bias),但这也意味着 MLP 难以捕获到变化剧烈的区域的特征(即高频特征)。 对于 Positional Encoding,从一方面来讲,它将欧式空间的样本点投影到频率空间,也就是将点打散了,在欧式空间相近的点在频率空间就会很远。原本 MLP 很难拟合出“狭小”的欧式空间中的剧烈变化。但在 Positional Encoding 将样本点投影到频率空间后,这些“剧烈变化”在频率空间就显得平滑得多, MLP 就能够很轻易地在频率空间拟合出这些变化,但频率空间相较于欧式空间得求解空间大得多,所以 MLP 依旧需要花费大量的时间去拟合。 从另一个角度来说,NeRF 想做的事情是表征欧式空间中的一个场,而 Positional Encoding 则是对欧式空间的三个轴分别引入了一组正交基函数,此时 MLP 的任务就可以看作是学习得到这三组正交基函数的系数表示,这个任务相比于让 MLP 去拟合高频特征显然要简单得多
很多人疑问为什么一开始的 NeRF 需要 Coarse-to-Fine 策略,甚至需要两个 MLP,一个负责 Coarse,一个负责 Fine,两个 MLP 之前并不共享参数和交流梯度。 直白的说就是希望样本点分布在光线与物体相交的表面附近,这样效果会更好,因此 NeRF 的 Hierarchical Sampling 就是对 Coarse 阶段输出的 density 计算 PDF、CDF 然后采样得到 Fine 阶段的样本点。 这在测试阶段没有问题,可是,为什么这需要两个 MLP 呢?也许作者是做了实验之后发现一个 MLP 负责 Coarse 和 Fine 并不能取得很好的结果,所以用两个 MLP 分别负责 Coarse 和 Fine 两个阶段(我相信也有不少研究者做了这个实验)。 我个人对此的理解是,虽然 CoarseMLP 和 FineMLP 仅在样本点的输入上有所不同(同样的 Positional Encoding 和 MLP)但其样本点的分布本身就决定了各自 MLP 能够在何种程度“看到”低频和高频信号。CoarseMLP 的样本点是光线在 near/far 区间上的均匀采样,这意味着这条光线上样本点的高频信号失真了(远处的也会包含高频信号,后面的 Mip-NeRF 会提及);而 FineMLP 是在表面交点附近的密集采样,这意味着 MLP 能够密集地“感受”到这一段区域的高频信号(尽可能保证不失真)。 可以理解为采用不同的采样策略就是施加了不同的“滤波器”。对同一条光线,两组不同的采样使得 MLP “看到”截然不同的两组信号;如果想让一个 MLP 同时处理好这两组截然不同的信号,可能得高超的调参技巧与更大的网络了。 至于为什么后面 Mip-NeRF 能用一个 MLP 来做 Coarse-to-Fine,个人认为他解决了上面我说的不同采样策略导致“滤波”行为
课程 教程
当前相关的课程很少,这里推荐基于NeRF的三维内容生成
NeRF++作者亲授,可行方向分析,助您快速产出顶尖成果
CVPR 2020 tutorial on Neural Rendering
用深度学习完成3D渲染任务的蹿红 一文详细描述了NeRF的训练流程并且给出了详细的代码解析
对于光线步进不太熟悉的可参考体积云渲染实战:ray marching,体积云与体积云光照
NeRF 背景、改进、应用与发展
- 提出了一种5D的神经辐射场来作为复杂场景的隐式表示
- 基于经典的volume rendering技术提出了一种可微渲染的过程
- 提出了位置编码(positional encoding)将5D输入映射到高维空间
原理说的倒是很简单,怎么看代码理解呢?
选用的代码是nerf-pytorch
数据加载、模型构建、光线生成、Pytorch版NeRF实现以及代码注释
体积渲染、位置编码
Nerf源码解析——Pytroch3D版 深度解读nerf-pytorch项目 nerf-pytorch代码逐行分析
NeRF的在训练中输的数据是:从不同位置拍摄同一场景的图片,拍摄这些图片的相机位姿、相机内参,以及场景的范围。若图像数据集缺少相机参数真值,作者便使用经典SFM重建解决方案COLMAP估计了需要的参数,当作真值使用。
在训练使用NeRF渲染新图片的过程中,先将这些位置输入MLP以产生volume density和RGB颜色值;取不同的位置,使用体积渲染技术将这些值合成为一张完整的图像;因为体积渲染函数是可微的,所以可以通过最小化上一步渲染合成的、真实图像之间的差来训练优化NeRF场景表示。这样的一个NeRF训练完成后,就得到一个 以多层感知机的权重表示的 模型。一个模型只含有该场景的信息,不具有生成别的场景的图片的能力。
代码实践
看到效果这么好?是不是忍不住想自己训练几个了呢?别急,NeRF对训练数据非常挑剔,先把这几个小建议看完再拍数据也不迟 训练NeRF模型的几个建议
这里推荐全流程的
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)