😸NeRF(ECCV 2020)主要贡献:
- 提出一种将具有复杂几何性质和材料的连续场景表示为 5D 神经辐射场的方法,并将其参数化为基本的 MLP 网络
- 提出一种基于经典体渲染技术的可微渲染方式,论文用它来优化标准 RGB 图像的表示
- 提出位置编码将每个输入 5D 坐标映射到高维空间,这使得论文能够成功优化神经辐射场来表示高频场景内容
前言
5D 坐标
😸论文提出了一种通过使用稀疏的输入图像集优化底层连续体积场景函数(volumetric scene function)的方法,从而达到了合成复杂场景新视图的 SOTA
。论文的算法使用全连接深度网络表示场景,网络的输入是包括3D 位置信息 和视角方向 的单个连续的 5D 坐标,其输出是该空间位置的体积密度 和与视图相关的 RGB 颜色,接着使用经典的体绘制技术将输出的颜色和密度投影到图像中。优化合成新视图所需要的唯一输入是一组具有已知相机位姿的图像(NeRF 中的 lego 小车使用 100
张图像),而 5D 坐标是通过沿着对应像素的相机光线采样所得到的。
坐标变换
三种坐标系:
- 世界坐标系:表示物理上的三维世界
- 相机坐标系:表示虚拟的三维相机坐标
- 图像坐标系:表示二维的图片坐标
😺相机坐标 和世界坐标 之间存在如下转换关系:
✍️其中,矩阵 是一个仿射变换矩阵,也可叫做相机的外参矩阵; 包含旋转信息; 包含平移信息。
🙀对于二维图片的坐标 和相机坐标系下的坐标 存在如下转换关系:
✍️其中,矩阵 为相机的内参矩阵(透视投影矩阵),包含焦距 以及图像中心点的坐标 。
😸论文使用数据集的配置文件 *.json
中的 transform_matrix
为上面所述仿射变换矩阵 的逆矩阵 ;而 camera_angle_x
是相机的水平视场 (horizontal field of view),可以用于算焦距。
常见图像质量评估指标
- 结构相似性 SSIM:一种衡量两幅图像相似度的指标,其值越大则两张图片越相似(范围为 )。给定两张图片 和 ,其计算公式如下:
✍️其中, 为 的均值, 为 的均值, 为 的方差, 为 的方差, 为 和 的协方差,,,,, 为像素值的动态范围(如 255
)。
- 峰值信噪比 PSNR:一般用于衡量最大值信号和背景噪音之间的图像质量参考值,其值越大图像失真越少(单位为
dB
)。一般来说,PSNR 高于40dB
说明图像质量几乎与原图一样好;在30-40dB
之间通常表示图像质量的失真损失在可接受范围内;在20-30dB
之间说明图像质量比较差;PSNR 低于20dB
说明图像失真严重。给定一个大小为 的原始图像I
和带噪声的图像K
,首先需要计算这两张图像的均方误差MSE
,接着再通过 MSE 计算峰值信噪比PSNR
,其计算公式如下:
✍️其中, 为图像 I
可能的最大像素值, 和 分别为图像 I
和 K
对应位置 的像素值。
- 学习感知图像块相似度 LPIPS:用于计算参考图像块 和失真图像块 之间的距离,其值越小则相似度越高。LPIPS 先提取特征并在通道维度中进行单元归一化,对于 层,我们将得到的结果记为 ,。接着,再利用向量 缩放激活通道并计算 距离,最后在空间上求平均值,在信道上求和。其公式如下:
✍️若对该指标的细节感兴趣,可参考这篇文章。
网络结构
😸神经辐射场 NeRF 是 Neural Radiance Fields 的缩写,其可以简要概括为用一个 MLP 神经网络去隐式地学习一个静态 3D 场景。为了训练网络,针对一个静态场景,需要提供大量相机参数已知的图片。基于这些图片训练好的神经网络,即可以从任意角度渲染出图片的结果。以下为 NeRF 的总体框架:
- 获取采样点的 5D 坐标 ,该坐标包含 3D 位置信息 和视角方向 。
- 通过位置编码对 3D 位置 和视角方向 进行相应处理,从而得到编码后的信息 和 。对于编码后的维度可参考后面位置编码章节做理解。
- 将 输入到
8
层全连接层中,每层通道数为256
且都经过ReLU
函数激活(黑色实箭头)。此外,论文还遵循DeepSDF
架构,将通过一个跳连接将输入 拼接到第5
个全连接层的输出中。 - 在第 8 个全连接层后添加一个新的全连接层,该层通道数为 256 且不经过激活函数(橙色箭头)。其输出为维度 256 的中间特征 和体素密度 (可近似理解为不透明度,值越小越透明)。对于 ,论文通过激活函数 ReLU 来确保其为非负的。
- 将编码后的视角方向 和中间特征 拼接起来,然后送入输出通道数为
128
的全连接层中,再经过激活函数ReLU
处理得到特征 。 - 将 送入全连接层中,再经过
sigmoid
激活函数(黑色虚箭头)处理得到三维的 RGB 输出。 - 通过体渲染技术利用上面输出的颜色和体密度来合成图像。由于渲染函数是可微的,所以可以通过最小化合成图像与真实图像之间的误差(residual)来优化场景表示。
✍️NeRF 中输出 只与位置有关,而颜色 RGB 还与视角方向相关。
体渲染
😸体密度 可解释为射线在 位置终止于无穷小的粒子的微分概率(简单理解为不透明度),而相机射线 的期望颜色 在近界 和远界 下为:
✍️函数 表示射线从 到 沿射线累积透射率,即射线从 到 不碰到其他任何粒子(particle)的概率。前面累积的体积密度 越大(非负),则 越小,从而降低(因为遮挡)该位置对颜色的影响:当前区域体积密度 越高,对颜色影响越大,但其会降低后面区域对颜色的影响(例如前面区域完全不透明,那么后面区域不管什么颜色,都不会影响该方向物体的颜色)。因此,这里根据 来降低相应区域对颜色的影响。
🙀通过对所需虚拟相机(virtual camera)的每个像素的光线计算这个积分 来为连续的神经辐射场绘制视图,从而得到颜色值。论文用求积法对这个连续积分进行数值估计,而确定性求积(deterministic quadrature)通常用于绘制离散体素网格。因为 MLP 只会在一些固定的离散位置集上执行,所以它会有限制表示的分辨率(representation’s resolution)。相反,论文采用分段抽样方法(stratified sampling),将 划分为 等分,然后从每一块中均匀随机(uniformly at random)抽取一个样本:
🙀虽然论文使用离散的样本集来估计积分,但因为分段抽样会导致 MLP 在优化过程中的连续位置被评估,从而能够表示一个连续的场景。论文使用 Max
在体绘制综述中讨论的正交规则(quadrature rule)和这些离散的样本来估计 :
✍️其中, 为相邻两个采样点之间的距离。这个从 值集合计算 的函数是可微的。因此,基于这样的渲染方式就可以用 NeRF 函数从任意角度中渲染出图片。
位置编码
🙀尽管神经网络是通用的函数近似器(universal function approximators),但其在表示颜色和几何形状方面的高频变化方面表现不佳,这表明深度网络偏向于学习低频函数。论文表明,在将输入传递给网络之前,使用高频函数将输入映射到更高维度的空间,可以更好地拟合包含高频变化的数据。 为了能有效提升清晰度,论文引入了位置编码,将位置信息映射到高频空间,从而将 MLP 表示为 ,位置编码 表达式如下:
✍️其中, 仍然是一个 MLP
,而 是从 维空间到高维空间 的映射, 分别应用于 中的三个坐标值(被归一化到 )和笛卡尔视角方向单位向量(Cartesian viewing direction unit vector) 的三个分量(其范围为 )。计算 时 , 即维度为 ;计算 时 ,即维度为 。
多层级体素采样
😸NeRF 的渲染过程计算量很大,每条射线都要采样很多点。但实际上,一条射线上的大部分区域都是空区域,或者是被遮挡的区域,对最终的颜色没啥贡献,而原始方法会对这些区域重复取样,从而降低了效率。因此,论文引入多层级体素采样( Hierarchical volume sampling),采用了一种 “coarse to fine"
的形式,同时优化 coarse 网络和 fine 网络。对于 coarse 网络,论文采样较为稀疏的 个点,并将前述式子 (3)
的离散求和函数重新表示为:
😸然后对权值做归一化: ,此处的 可以看作是沿着射线的概率密度函数(PDF),通过这个概率密度函数可以粗略地得到射线上物体的分布情况。接下来,基于得到的分布使用逆变换采样(inverse transform sampling)来采样 个点,并用这 个点和前面的 个点通过前面公式 (3)
一同计算 fine 网络的渲染结果 。虽然 coarse to fine 是计算机视觉领域中常见的一个思路,但这篇论文中用 coarse 网络来生成概率密度函数,再基于概率密度函数采样更精细的点算的上是很有趣新颖的做法。采样的图示如下:
✍️上图中,白色的点为第一阶段采样的 个点,而黄色的点为第二阶段根据 PDF 采样的 个点。
损失函数
😺由于渲染函数是可微的,所以可以通过下式来计算损失:
✍️其中 为每批射线的集合,、、 分别为射线 的 ground truth
、粗体积(coarse volume)预测、精体积(fine volume)预测的 RGB 颜色。虽然最终的渲染来自 ,但也要同时最小化 的损失,从而使粗网络的权值分布可以用于细网络中的样本分配。
代码运行结果
😻以下是运行 200k 轮后生成的 lego 模型(显卡 RTX3060 6G,训练时间约 15h),代码使用 pytorch 版本(文末有附地址)
✍️在训练过程中,渲染时出现 GPU 内存不足,可通过减少 chunk 大小解决问题
# parser.add_argument("--chunk", type=int, default=1024*32,
parser.add_argument("--chunk", type=int, default=1024*16,
help='number of rays processed in parallel, decrease if running out of memory')
🙀以下是消融实验的部分结果:
- 移除
View Dependence
(即不使用视角方向 )会阻碍模型在推土机胎面上重新创建镜面反射(specular reflection) - 移除位置编码大大降低了模型表示高频几何和纹理的能力,导致外观过平滑
😻pytorch 版 NeRF(速度比原始代码快大约 1.3 倍):https://github.com/yenchenlin/nerf-pytorch
😻文章:https://arxiv.org/pdf/2003.08934.pdf
😻项目地址:https://www.matthewtancik.com/nerf
📖文章补充:【NeRF论文笔记】用于视图合成的神经辐射场技术、NeRF:用深度学习完成3D渲染任务的蹿红、NeRF论文阅读、【3D】NeRF论文随笔、【学习笔记】NeRF
文章出处登录后可见!