文章目录
- 引言
- NeRF资料
- 技术基础梳理
-
- 算法概览
- 使用神经辐射场(Neural Radiance Field)来表示场景
- 基于辐射场的体素渲染算法
-
- 经典体素渲染算法
- 数值近似法
- 优化神经辐射场
-
- 位置信息编码(Positional encoding)
- 采样多层次体素
- 实现细节
- 时间消耗
引言
NeRF是2020年ECCV本技术的提出是从新的角度进行合成研究。在深度学习技术的帮助下,研究人员实现了摄像逼真的新视图合成,效果惊人。关于过去不到两年,关于NeRF论文数量已经相当可观了。与计算机视觉相比,特别是与基于深度学习的计算机视觉相比,计算机图形学更加困难和模糊。计算机视觉任务被深度学习席卷,但被深度学习席卷的计算机图形学任务仍然很少。 除本文外,我还将继续介绍一些相关的改进或应用。
NeRF资料
项目地址: https://www.matthewtancik.com/nerf 论文地址: https://arxiv.org/abs/2003.08934 开源代码地址: TensorFlow实现:https://github.com/bmild/nerf PyToch实现:https://github.com/yenchenlin/nerf-pytorch 官方数据地址: https://drive.google.com/drive/folders/128yBriW1IG_3NJ5Rp7APSTZsJqdJdfc1 相关技术分析文章: https://zhuanlan.zhihu.com/p/360365941 https://wandb.ai/sweep/nerf
技术基础梳理
算法概览
NeRF可以简要概括为使用一个MLP神经网络去隐式学习静态3(主要由全连层而非卷积层和激活层组成)D场景的目的是实现复杂场景的任何新视角合成(渲染)。
为了训练网络,对于静态场景,需要提供大量相机参数已知图片的训练集,以及图片对应的相机所在3D坐标,相机朝向(2)D,但实际使用3D单位向量表示方向)。
利用多视角数据进行训练,空间中包含真实场景的位置具有更高的密度和更准确的颜色,鼓励神经网络预测场景模型。
在任何相机位置 方向作为输入,通过训练好的神经网络绘制身体(Volume Rendering),图片结果可以从渲染出来。 
使用神经辐射场(Neural Radiance Field)来表示场景
NeRF函数将连续场景表示为D向量函数,包括3个空间点D坐标位置x=(x,y,z),以及方向(θ,?);
输出与视角相关的3D点的颜色c=(r,g,b),与相应位置(体素)的密度σ。
实践中,用3D笛卡尔单位向量d表示方向,所以这个神经网络可以写:Θ:(x,d)→(c,σ)。 在具体实现中,x首先输入到MLP并在网络中输出σ将中间特征和d与256维中间特征输入额外的全连接层(128维)中预测颜色。
因此,体素密度只与空间位置有关,而颜色与空间位置和观察视角有关。view dependent 的颜色预测,能够得到不同视角下不同的光照效果。
以下是神经网络的架构: 1.绿色表示输入向量,蓝色表示中间隐藏层,红色表示输出向量; “ ” 符号表示向量串联;黑色实线箭头表示使用隐藏层;ReLU激活,橙色实线箭头表示隐藏层不使用激活函数,黑色虚线箭头表示隐藏层使用sigmoid激活函数。
二、输入数据x和d首先通过位置信息编码(Position Encoding),即γ()操作,将原始输入数据映射到高频,使网络更容易理解和建模位置信息,提高渲染清晰度。
3.位置编码后的位置输入γ(x)8层256维全连接ReLU层,包括将该位置信息连接到第五层的激活层SKIP连接(激活后接入代码);输出体素密度的第9层σ使用256维特征向量ReLU来保证σ不包括负值;特征向量和位置编码γ(d)串联,再经过一个128维的全连接层,最后输出与方向d相关的位置x的颜色预测。
4.论文中提到的PE操作参数为:位置信息,L=视角信息,L=4.位置编码后的输入维度(60, 24)具体如何获得,但两者的比值与论文的参数设置相匹配。
5.上图中网络输入的位置信息是指每个相机原点引起的射线,通过相应图像中的每个像素,采样点的位置和方向是指射线的方向;输出的体质密度σ与方向相关的颜色值c=(r,g,b),该位置在后续渲染中提供的渲染结果的值共同确定;上述网络中的权重/参数共享所有像素射线。
基于辐射场的体素渲染算法
神经辐射场将一个场景表示为,空间中任意一个点(3D位置)体素密度σ以及与视角相关的辐射颜色。
但是当用相机成像场景时,得到2D 图像上的像素实际上对应着相机射线上的所有连续空间点。
我们需要通过渲染算法从这个射线上的所有点得到这个射线的最终渲染颜色。同时,为了确保网络能够训练,NeRF微渲染法需要在中间使用。
经典体素渲染算法
体素密度σ(x)可以理解为,一条穿过空间的射线在x处被无限小颗粒终止的概率可以微分,可以理解为位置点的不透明度。
虚拟相机沿特定方向观测,观测射线上的点是连续的,相机成像平面上相应的像素颜色可以理解为相应射线通过点的颜色点。
将射线的原点标记为o,射线方向(即相机视角)标记为d,射线可以表示为r(t)=o td,t近端和远端边界分别为tn和tf。
这种射线的颜色可以用积分来表示: 其中,T(t)表示射线从tn到t的累积透明度,即射线从tn具体写作: 在连续的辐射场中,为了渲染任何视角,需要通过目标虚拟相机的每个像素获得上述颜色点,以获得每个像素的颜色,并渲染视角下的成像图片。
数值近似法
在实际应用中,我们并不可能用NeRF估计连续3D点信息(射线上的连续点),这就需要数值近似的方法。论文中先提出了使用求积法(Quadrature)类似于连续积分的方法。
确定性求积(Deterministic Quadrature)通常用于渲染离散体素网格,通常在需要积累的区域均匀采样N点进行近似计算,但这会使MLP只学习一系列确定的离散点,从而极大地限制了神经辐射场的分辨率。
因此,作者提出了分层抽样(Stratified Sampling)方法:首先,射线需要积分的区域[tn,tf]均匀分为N份,然后在每个小区域均匀随机采样: 这种方法是在只采样离散点的前提下实现的MLP可以连续优化,保证辐射场对场景表达的连续性,如下图所示: 基于这些采样点,上述积分可以简化为求和形式: 其中,δi=ti 1?ti为两个近邻采样点之间的距离,此处T(t)改写作: 从所有采样点开始(ci,σi)收集和获得射线渲染颜色的方法也可以微分,可以简化为传统的透明混合算法,其中alpha值αi=1?exp(?σiδi)。
优化神经辐射场
继续介绍论文NeRF两个重要的创新点使神经辐射场能够表达复杂的高分辨率场景。
位置信息编码(Positional encoding)
作者发现,直接将位置和视角作为网络输入的结果,在表达高分辨率场景时表现不佳、模糊,使用位置信息编码将输入映射到高频可以有效地解决这个问题。
因此,将?Θ重写由两组函数组成:Θ=?′Θ°γ,其中?′Θ仍为常规MLP网络需要通过训练和学习获得,γ用于将输入映射到高维空间,在论文中使用R→R2L正余弦周期函数的形式: 论文首先将位置和视角信息归一化NDC(normalized device coordinate)在空间中,使其数值落在[-1、1]之间,然后进行PE操作。
使用不同参数的位置和视角信息L,在本文中 γ(x)设置 L=10;对于γ(d)设置 L=4。
a id="_94">多层级体素采样
NeRF的渲染策略是对相机出发的每条射线都进行N个采样点的求和计算。
这个策略效率是较低的,因为大量的对渲染没有贡献的空的或被遮挡的区域仍要进行采样计算,这样占用了过多的计算量。
作者提出按照对最终渲染的贡献比例进行采样,设计了一种“coarse to fine”的多层级体素采样方法,同时优化coarse和fine两个网络。
首先,使用分层采样的方法先采集较为稀疏的Nc个点,在这些采样点上计算coarse网络的渲染结果,改写前述的离散求和函数: ,其中,并对ωi进行归一化: 归一化后的ωi可以看作是沿着射线方向的概率密度函数,如下左图所示。通过这个概率密度函数,我们可以粗略地得到射线方向上物体的分布情况: 接下来,基于这个概率密度函数,使用逆变换采样(inverse transform sampling)方法,再采样出Nf个点,如上右图所示。
这个方法可以从包含更多可见内容的区域中得到更多的采样点,然后在Nc+Nf的采样点集合上,计算fine网络的渲染结果。
这达到了类似按权重采样的效果,作者将采样点视为非均匀的离散化,而非对每个点进行独立的概率估计。
实现细节
针对不同的场景,需要进行独立的训练。
需要的数据集由针对场景采集的多视角的RGB图像、对应的相机位姿、相机内参、以及场景的近端/远端边界信息(部分可从Colmap得到)。
在训练中的每一次迭代,从数据集中所有像素中随机选择,从对应像素点出发的射线,通过上述多层采样法得到coarse和fine的采样点,再通过体素渲染法得到对应的渲染结果。
训练损失直接定义在渲染结果上的L2损失(同时优化coarse和fine网络):
时间消耗
实现中使用4096个射线作为一个batch,Nc = 64, Nf = 128,针对一个场景一般需要100300K次迭代,在英伟达V100的显卡上训练12天。
推理1920*1080分辨率的图像,NeRF的速度为50s/帧(V100)。