NeRF:用深度学习完成3D渲染任务的蹿红

转自:Leviosa

1 引言

NeRF是2020年ECCV论文。仅仅过去不到2年,关于NeRF的论文数量已经十分可观。相比于计算机视觉,尤其是相比于基于深度学习的计算机视觉,计算机图形学是比较困难、比较晦涩的。被深度学习席卷的计算机视觉任务数不胜数,但被深度学习席卷的计算机图形学任务仍然尚少。

由于NeRF及其众多follow-up工作在图形学中非常重要的渲染任务上给出了优秀的结果,可以预见未来用深度学习完成图形学任务的工作会快速增长。今年的GIRAFFE是NeRF的后续工作之一,它摘下2021CVPR的最佳论文奖对整个方向的繁荣都起到积极的推动作用。

本文希望讨论以下问题:

  • NeRF被提出的基础(2 前NeRF时代);
  • NeRF是什么(3 NeRF!);
  • NeRF的代表性follow-up工作(4 后NeRF时代);
  • 包含NeRF的更宽泛的研究方向Neural Rendering的简介(5 不止是NeRF)。

2 前NeRF时代

2.1 传统图形学的渲染

本质上,NeRF做的事情就是用深度学习完成了图形学中的3D渲染任务。那么我们提两个问题。

  • 问题1:3D渲染是要干什么?

看2个比较官方的定义。

MIT计算机图形学课程EECS 6.837对渲染(Rendering)的定义:

“Rendering” refers to the entire process that produces color values for pixels, given a 3D representation of the scene.

综述State of the Art on Neural Rendering对渲染(Rendering)的定义:

The process of transforming a scene definition including cameras, lights, surface geometry and material into a simulated camera image is known as rendering.

也就是说,渲染就是用计算机模拟照相机拍照,它们的结果都是生成一张照片。

用照相机拍照是一个现实世界的物理过程,主要是光学过程,拍照对象是现实世界中真实的万事万物,形成照片的机制主要就是:光经过镜头,到达传感器,被记录下来。

而渲染就是用计算机模拟这一过程,模拟“拍照”的对象是已存在的某种三维场景表示(3D representation of the scene),模拟生成照片的机制是图形学研究人员精心设计的算法。

关键前提:渲染的前提是某种三维场景表示已经存在。渲染一词本身不包办生成三维场景表示。不过,渲染的确与三维场景表示的形式息息相关;因此研究渲染的工作通常包含对三维场景表示的探讨。

  • 问题2:3D渲染是图形学问题,那么原先大家是用什么传统图形学方法实现3D渲染的呢?

主要有两种算法:光栅化(rasterization),光线追踪(ray tracing);都是对照相机拍照的光学过程进行数学物理建模来实现的。

Rrasterization,Ray Tracing

传统渲染的详细原理参阅此教材

光栅化是一种前馈过程,几何体被转换为图像域,是上世纪比较早的算法。光线追踪则是将光线从图像像素向后投射到虚拟三维场景中,并通过从与几何体的交点递归投射新光线来模拟反射和折射,有全局光照的优势(能模拟光线的多次反射或折射)。

当下,在学术界,还在研究传统图形学的渲染算法的人应该大部分在搞优化加速,怎么用GPU实时渲染更复杂的场景之类的事儿。在工业界,不少游戏重度依赖渲染技术,所以应该也有不少游戏公司在研究更逼真、更快速、更省算力的渲染算法。去年虚幻引擎出的新款“虚幻引擎5”效果很是震撼,光照、纹理、流体的实时渲染模拟都逼真到了前所未有的新高度,可以看下虚幻引擎官方的宣传视频,真的很不错。

虚幻引擎5

2.2 神经网络侵略3D渲染任务:NeRF呼之欲出

隐式场景表示(implicit scene representation)

基于深度学习的渲染的先驱是使用神经网络隐式表示三维场景。 许多3D-aware的图像生成方法使用体素、网格、点云等形式表示三维场景,通常基于卷积架构。 而在CVPR 2019上,开始出现 使用神经网络拟合标量函数 来表示三维场景的工作。

DeepSDF

2019年CVPR的DeepSDF或许是最接近NeRF的先驱工作。

SDF是Signed Distance Function的缩写。DeepSDF通过回归(regress)一个分布来表达三维表面的。如下图所示,SDF>0的地方,表示该点在三维表面外面;SDF<0的地方,表示该点在三维表面里面。回归这一分布的神经网络是多层感知机(Multi-Layer Perceptron,MLP),非常简单原始的神经网络结构。

DeepSDF

NeRF比DeepSDF进步的地方就在于,NeRF用RGBσ代替了SDF,所以除了能推理一个点离物体表面的距离,还能推理RGB颜色和透明度,且颜色是view-dependent的(观察视角不同,同一物点的颜色不同),从而实现功能更强大的渲染。

3 NeRF!

建议前往NeRF项目网站查看视频效果图。

3.1 Radiance Fields(RF)

NeRF是Neural Radiance Fields的缩写。其中的Radiance Fields是指一个函数、或者说映射gθ 。

(σ,c)=gθ(x,d)

映射的输入是 x 和d 。 x∈R3是三维空间点的坐标, d∈S2 是观察角度。

映射的输出是 σ 和 c 。 σ∈R+ 是volume density(可以简单理解为不透明度), c∈R3 是color,即RGB颜色值。

Radiance Fields(RF)

Radiance Fields,或者说映射 gθ ,能对三维场景进行隐式表示(implicit scene representation)。在上一节,我们说过某种三维场景表示正是渲染的前提。实现渲染也是 作者提出Radiance Fields这一新型三维场景表示方法 的目的所在。

3.2 Neural Radiance Fields(NeRF)

Radiance Fields是映射gθ 。那么Neural Radiance Fields则是指用神经网络拟合Radiance Fields gθ 。论文中,该神经网络具体是多层感知机(与DeepSDF一样)。

Neural Radiance Fields(NeRF)

3.3 NeRF的体积渲染

NeRF(Neural Radiance Fields)其实是一种三维场景表示(scene representation),而且是一种隐式的场景表示(implicit scene representation),因为不能像point cloud、mesh、voxel一样直接看见一个三维模型。

NeRF将场景表示为空间中任何点的volume density σ 和颜色值 c 。 有了以NeRF形式存在的场景表示后,可以对该场景进行渲染,生成新视角的模拟图片。论文使用经典体积渲染(volume rendering)的原理,求解穿过场景的任何光线的颜色,从而渲染合成新的图像。

NeRF volume rendering

3.4 NeRF的训练

训练NeRF的输入数据是:从不同位置拍摄同一场景的图片,拍摄这些图片的相机位姿、相机内参,以及场景的范围。若图像数据集缺少相机参数真值,作者便使用经典SfM重建解决方案COLMAP估计了需要的参数,当作真值使用。

在训练使用NeRF渲染新图片的过程中,

  • 先将这些位置输入MLP以产生volume density和RGB颜色值;
  • 取不同的位置,使用体积渲染技术将这些值合成为一张完整的图像;
  • 因为体积渲染函数是可微的,所以可以通过最小化上一步渲染合成的、真实图像之间的差来训练优化NeRF场景表示。

这样的一个NeRF训练完成后,就得到一个 以多层感知机的权重表示的 模型。一个模型只含有该场景的信息,不具有生成别的场景的图片的能力。

除此之外,NeRF还有两个优化的trick:

  • 位置编码(positional encoding),类似于傅里叶变换,将低维输入映射到高维空间,提升网络捕捉高频信息的能力;
  • 体积渲染的分层采样(hierarchical volume sampling),通过更高效的采样策略减小估算积分式的计算开销,加快训练速度。

4 后NeRF时代

GIRAFFE:composition方向的代表作

2021CVPR的最佳论文奖得主GIRAFFE是NeRF、GRAF工作的延申。

在NeRF之后,有人提出了GRAF(Generative Radiance Fields),关键点在于引入了GAN来实现Neural Radiance Fields;并使用conditional GAN实现对渲染内容的可控性。

在GRAF之后,GIRAFFE实现了composition。在NeRF、GRAF中,一个Neural Radiance Fields表示一个场景,one model per scene。而在GIRAFFE中,一个Neural Radiance Fields只表示一个物体,one object per scene(背景也算一个物体)。这样做的妙处在于可以随意组合不同场景的物体,可以改变同一场景中不同物体间的相对位置,渲染生成更多训练数据中没有的全新图像。

GIRAFFE实现composition

如图所示,GIRAFFE可以平移、旋转场景中的物体,还可以在场景中增添原本没有的新物体。

另外,GIRAFFE还可以改变物体的形状和外观,因为网络中加入了形状编码、外观编码变量(shape codes zsi , appearance codes zai )。

其他最新相关工作

2021年CVPR还有许多相关的精彩工作发表。例如,提升网络的泛化性:

  • pixelNeRF:将每个像素的特征向量而非像素本身作为输入,允许网络在不同场景的多视图图像上进行训练,学习场景先验,然后测试时直接接收一个或几个视图为输入合成新视图。
  • IBRNet:学习一个适用于多种场景的通用视图插值函数,从而不用为每个新的场景都新学习一个模型才能渲染;且网络结构上用了另一个时髦的东西 Transformer。
  • MVSNeRF:训练一个具有泛化性能的先验网络,在推理的时候只用3张输入图片就重建一个新的场景。

针对动态场景的NeRF:

  • Nerfies:多使用了一个多层感知机来拟合形变的SE(3) field,从而建模帧间场景形变。
  • D-NeRF:多使用了一个多层感知机来拟合场景形变的displacement。
  • Neural Scene Flow Fields:多提出了一个scene flow fields来描述时序的场景形变。

其他创新点:

  • PhySG:用球状高斯函数模拟BRDF(高级着色的上古神器)和环境光照,针对更复杂的光照环境,能处理非朗伯表面的反射。
  • NeX:用MPI(Multi-Plane Image )代替NeRF的RGBσ作为网络的输出。

5 不止是NeRF:Neural Rendering

Neural Radiance Fields的外面是Neural Rendering;换句话说,NeRF(Neural Radiance Fields)是Neural Rendering方向的子集。

在针对这个更宽泛的概念的综述State of the Art on Neural Rendering中,Neural Rendering的主要研究方向被分为5类,NeRF在其中应属于第2类“Novel View Synthesis”(不过这篇综述早于NeRF发表,表中没有NeRF条目)。

Neural Rendering的5类主要研究方向

表中彩色字母缩写的含义:

在这篇综述中,Neural Rendering被定义为:

Deep image or video generation approaches that enable explicit or implicit control of scene properties such as illumination, camera parameters, pose, geometry, appearance, and semantic structure.

Neural Rendering包含所有使用神经网络生成可控(且photo-realistic)的新图片的方法。“可控”指人可以显式或隐式地控制生成新图片的属性,常见的属性包括:光照,相机内参,相机位姿(外参),几何关系,外观,语义分割结构。在这个大框架下,NeRF是一种比较受欢迎的可控相机位姿的Neural Rendering算法。但Neural Rendering这个方向不止于此。

在目前的Neural Rendering方向,最火的子方向就是“Novel View Synthesis”,这与NeRF的强势蹿红密不可分;第二火的子方向是“Semantic Photo Synthesis”,这主要归功于语义分割以及相关的GAN领域的成熟度。“Semantic Photo Synthesis”方向也是成果颇丰,例如2019年CVPR的Semantic Image Synthesis with Spatially-Adaptive Normalization,其效果图如下。

Semantic Image Synthesis

相关资源

Github论文收集仓库

小仓库(仅限于NeRF):

https://github.com/yenchenlin/awesome-NeRF

大仓库(neural rendering):

https://github.com/weihaox/awesome-neural-rendering

综述论文

可以说是官方综述,作者列表是目前在Neural Rendering领域最活跃的一群人。两篇分别是2021、2020年的SIGGRAPH、CVPR讲座用到的综述,很全面很有条理,值得每位从业者一读!

SIGGRAPH 2021 Course: Advances in Neural Rendering

CVPR 2020 Tutorial: State of the Art on Neural Rendering

范围限定为可微渲染方法的综述:

Differentiable Rendering: A Survey

上面小仓库的库主(MIT博士生Yen-Chen Lin)写的综述:

Neural Volume Rendering: NeRF And Beyond

论文

列论文实在挂一漏万,象征性地放上本文提到的2篇很重要的论文吧。

NeRF项目主页:

NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis

GIRAFFE项目主页:

GIRAFFE: Representing Scenes as Compositional Generative Neural Feature Fields

教材

传统图形学渲染技术:

Real-Time Rendering 3rd

计算机视觉经典教材,含有image-based rendering章节:

Computer Vision: Algorithms and Applications

三篇Georgia Tech老师写的博客

NeRF at CVPR 2022 – Frank Dellaert

NeRF at ICCV 2021 – Frank Dellaert

NeRF Explosion 2020 – Frank Dellaert

离散形式

推导一下连续形式变为离散形式的运算。

计算机求解积分式的办法一般是化为黎曼和。在这里,如果我们每次都将积分区间划分为固定的、等间距的窄长方形面积和,其实就失去了NeRF是连续场景表示的优势:因为虽然每个点的RGBσ都可以访问,但是实际上你还是只用了固定点的值求积分。

GIRAFFE—NeRF、GRAF工作的延申

GIRAFFE: Representing Scenes as Compositional Generative Neural Feature Fields

论文报告: https://www.bilibili.com/video/BV1TX4y1P7ou/

github: https://github.com/autonomousvision/giraffe

GIRAFFE:composition方向的代表作

2021CVPR的最佳论文奖得主GIRAFFE是NeRF、GRAF工作的延申。

在NeRF之后,有人提出了GRAF(Generative Radiance Fields),关键点在于引入了GAN来实现Neural Radiance Fields;并使用conditional GAN实现对渲染内容的可控性。

在GRAF之后,GIRAFFE实现了composition(创作)。在NeRF、GRAF中,一个Neural Radiance Fields表示一个场景,one model per scene。而在GIRAFFE中,一个Neural Radiance Fields只表示一个物体,one object per scene(背景也算一个物体)。这样做的妙处在于可以随意组合不同场景的物体,可以改变同一场景中不同物体间的相对位置,渲染生成更多训练数据中没有的全新图像。

GIRAFFE实现composition

如图所示,GIRAFFE可以平移、旋转场景中的物体,还可以在场景中增添原本没有的新物体。另外,GIRAFFE还可以改变物体的形状和外观,因为网络中加入了形状编码、外观编码变量(shape codes zsi , appearance codes zai )。

GIRAFFE是一个基于学习的、完全可微的渲染引擎,用于将场景合成为多个“特征域”的总和。

简单回顾一下nerf,它们是一种描述和渲染3D场景的方法,在3D体积中任何给定的点上它的密度和辐射。它与光场的概念密切相关,光场是表达光如何流经给定空间的函数。对于空间中给定的(x,y,z)视点,图像将方向(θ, φ)的射线投射到一个场景中。对于这条线上的每个点,我们收集其密度和视相关的发射辐射,并以类似于传统光线追踪的方式将这些光线合成为单个像素值。这些NeRF场景是从各种姿势拍摄的图像收集学习,你会使用在结构从运动应用程序。

传统的GAN架构使用编码器和解码器设置,就像下图这样。在训练过程中,编码器接收一个图像,将其编码成一个压缩的表征,解码器利用这个表征来创建一个改变样式的新图像。在我们的训练数据集中的所有图像中重复多次,以便编码器和解码器学习如何在训练期间最大化我们想要实现的任务的结果。一旦训练完成,你可以发送一个图像到编码器,它会做同样的过程,生成一个新的和看不见的图像,根据你的需要。无论做什么工作,它都会起到非常相似的作用,不管是把一张脸的图像翻译成卡通画家那样的另一种风格,还是用草图创造出一幅美丽的风景。仅使用解码器,我们也称之为生成器,因为它是负责创建新图像的模型,我们可以在这个编码信息空间中行走,并对发送给生成器的信息进行采样,以生成无限量的新图像。这种编码的信息空间通常被称为潜在空间,而我们用来生成新图像的信息就是潜在代码。我们基本上是在这个最优空间内随机选择一些潜在的代码,然后它会根据我们想要完成的任务生成一个新的随机图像,当然,也会遵循这个生成器的训练过程。这是难以置信的酷,但正如我刚才所说,图像是完全随机的,我们没有或很少的想法,它看起来像什么,这已经是一个非常少有用的创造者。

这就是他们用这篇论文解决的问题。实际上,通过获取物体形状和外观的潜在代码并将其发送给解码器或生成器,他们能够控制物体的姿势,这意味着他们可以移动物体,改变物体的外观,添加其他物体,改变背景,甚至改变相机的姿势。所有这些变换都可以在每个对象或背景上独立完成,而不会影响图像中的任何其他内容!

如你看到的那样子,它比其他基于GAN的方法要好得多,这些方法通常无法将对象彼此分离,并且都会受到特定对象修改的影响。

与他们的方法不同的是,他们在三维场景表示中解决这个问题,就像我们如何看待现实世界一样,而不是像其他GANs那样停留在二维图像世界中。但除此之外,过程非常相似。它们对信息进行编码,识别对象,在潜在空间内对其进行编辑,然后解码生成新的图像。在这里,在这个潜在的空间里还有更多的步骤要做。我们可以将其视为经典GAN图像合成网络与神经渲染器的结合,神经渲染器用于从发送到网络的图像生成3D场景,正如我们看到的。

实现这一目标主要有三个步骤。对输入图像进行编码后,意味着我们已经处于潜在空间中,第一步是将图像转换为三维场景。但不仅仅是一个简单的3D场景,一个由3D元素组成的3D场景,即物体和背景。这种将图像视为由生成的体渲染组成的场景的方式允许它们更改生成图像中的摄影机角度并独立地控制对象。这是通过使用模型NERV来实现的,但是它们没有使用一个模型从输入图像生成整个锁定场景,而是使用两个单独的模型独立地生成对象和背景。这里称为采样特征字段。该网络的参数也在训练过程中学习。它与NERF非常相似。

有了这个场景和分离的元素,我们可以单独编辑它们而不影响图像的其余部分。这是第二步。他们可以对物体做任何他们想做的事情,比如改变它的位置和方向。换句话说,它们改变了物体或背景的姿势。在这一点上,他们甚至可以添加新的对象放置在他们想要的任何地方。然后,通过将所有特征字段添加到一起,将它们简单地组合到包含所有对象和背景的最终三维场景中。

最后,我们必须回到自然图像的二维世界。所以最后一步是把这个3D场景渲染成一个规则的图像。由于我们仍然处于三维世界中,我们可以改变相机的视点来决定我们将如何看待场景。然后,我们根据该相机光线和其他参数(如alpha值和透射率)对每个像素进行评估。这就是他们所说的特征图像,但是这个特征图像是由每个像素的特征向量组成的图像。由于我们仍处于潜在空间,这些特征需要转化为RGB颜色和高分辨率图像。这是通过使用典型的解码器来完成的,就像其他GAN架构一样,将其放大到原始尺寸,同时学习RGB通道的特征转换。瞧à, 你有你的新形象,有更多的控制,什么是生成!

当然,正如你所看到的,它在实际数据中使用时仍然不是完美的。尽管如此,它仍然令人印象深刻,是朝着正确方向迈出的重要一步,特别是考虑到这些都是完全由GANs生成的合成图像,而且它只是第一篇能够以这种精度控制生成图像的论文。

参考资料:

  • Michael Niemeyer and Andreas Geiger, (2021), “GIRAFFE: Representing Scenes as Compositional Generative Neural Feature Fields”, Published in CVPR 2021.
  • Project link with paper and more: https://m-niemeyer.github.io/project-pages/giraffe/index.html
  • Code: https://github.com/autonomousvision/giraffe
  • NERF video: https://youtu.be/ZkaTyBvS2w4

计算机图形学——网格

网格有多种,三角形,四边形或者其他的多边形。但是目前使用最多的,也是本文着重介绍的是三角网格。三角网格是计算机中表示三维模型最重要的方法。这篇文章主要介绍一下网格的相关概念以及技术算法。

定义

网格就是使用多边形来表示物体的表面。一个网格模型的描述之前也说到过,它包含一系列的面片和顶点。

面片F=(f1,…,fn)F=(f1,…,fn),对于三角网格,每个面片都是三角形。

顶点V=(v1,…,vm)V=(v1,…,vm)。其中,每个面片又是由3个顶点构成的三角形,因此:fi=(vi1,vi2,vi3);vi1,vi2,vi3∈V.fi=(vi1,vi2,vi3);vi1,vi2,vi3∈V.

网格的由来

计算机生成的三维模型和实际获取的数据表示模式是不同的。计算机生成的模型可能是平滑曲线曲面,而实际获取的数据,如激光扫描得到的,一般都是以点云的形式存在。图形学中需要一个统一的表示方式,同时要求视觉精度和处理速度都在可以接受的范围内。于是就选择了网格,用多边形来近似曲面,三角网格最为简单高效,再加上图形硬件的快速发展,三角网格和光栅化已经可以嵌入到硬件中去渲染。

三维数据的来源

一般来说,获取三维模型数据的方法有多种。我们可以直接在几何文件中输入,也可以通过程序创建,比较高级的建模软件有3Ds/max,maya等。第二种就是通过激光扫描,结构光技术等等获取深度,得到点云模型。也有一些别的方法,如SFM,从多视图(多张照片)中构建三维模型。

三维模型又可以分为实体模型和表面模型。

  • 实体模型,多用于CAD领域,通常强调对应实际工业生产中的加工过程,如切割,钻孔等。它是实心的而非空心,在显示过程中需要考虑很多的东西,占用内存较大,因此不利于显示。
  • 表面模型,我们平时见到的模型多是表面模型,只考虑物体的表面细节并直接进行处理,这种模型易于显示。

网格化

网格化是指将模型(点云,多边形等等)分割称为更容易处理的图元,如凸多边形,三角形或者四边形。如果分割成三角形,被称为三角化。我们先看看2D网格化,而3D空间中的网格化也和2D中类似。

如上图,最左侧的多边形不能被称作网格化,第二个是凸多边形网格化,第三个是三角化,最右侧是被均匀分割。

这里介绍两个三角网格化的非常简单的算法。

  • 基本的网格化算法

给定多边形,检验其任意两个顶点之间的线段是否与该多边形的边相交或者部分重叠。如果是,则不能用于分割三角形,否则,用该线段来将多边形分成两个多边形,对每个部分继续上述算法。

  • 割耳(ear clipping)算法

首先找到多边形的ear:查看所有具有顶点序列i,i+1,i+2(modn)i,i+1,i+2(modn)的三角形,称这个三角形为顶点为i+1i+1的三角形,检查线段i,i2i,i2是不是没有与任何边相交。如果是,则这个三角形构成一个ear,去掉该ear,检查顶点ii和i+2i+2处的三角形是不是构成ear。重复上述过程。这个算法每次都会分出一个新的三角形。

上述两种算法对凹多边形进行三角化,会使得其变成凸多边形的样子。原本不是面的部分由于三角化而多了面片。

除此之外,我们还需要注意一种特殊的情况叫T型顶点:

它最常出现在网格细分或者网格简化过程中,使得一个顶点出现在了某个面片的边上。理论上这个点是完全在边上,但是实际渲染中顶点的位置可能不会那么精确。当一个模型中有T顶点存在,一些算法可能会失败。

网格简化

网格的简化有很多好处。比如当前我做的项目中,就需要网格简化来节省内存。同时,网格简化还有很多好处。

  • 减少几何冗余:如果一个具有很多共面小三角形的平坦区域,可以将这些小三角形合并成大的多边形来降低模型复杂度。
  • 减小模型大小
  • 提高运行性能

而且有时候,对于网格的简化,并不会引起多大的感官差异,例如我们可以对较远的场景进行网格简https://www.baidu.com/baidu?wd=163&tn=ubuntuu_cb&ie=utf-8的东西看不清,复杂的网格和简化之后的网格差别不大。这也是当前很多游戏能实时运行的一个重要的技术,叫做生成场景中物体的层次细分。

拓扑结构

拓扑结构指的是多边形网格的连接结构。有一些专业术语需要了解一下,对于网格简化,细分等会用到。

  • 亏格(genus)
    亏格指的是网格表面孔洞的数目。如下:
  • 面片,边或顶点的拓扑结构,指相邻元素的局部连接关系。如下图:

临界边只接一个三角形, 普通边接两个三角形, 奇异边接三个三角形。对于没有临界边的网格称为closed mesh。

  • 二维流形(2-manifold)

二维流行网格定义如下:

  1. 一条网格边为一个或两个网格三角面片共享;
  2. 一个网格顶点的一环邻域三角片构成一个闭合或者开放的扇面。

看上去不好理解,看图片就比较好明白。

非流形网格:

流形网格:

很显然,流形网格只包含临界边和普通边。

网格简化的方法有很多,但是不外乎是下面四种的改进或者组合。

  • 采样(sample)。很好理解,简单的选取模型表面上的点进行几何采样,编程较为复杂。这种方法对高频特征难以精确采样,通常在没有尖角的光滑表面上能取得最好的效果。
  • 自适应细分(adaptive subdivision)通过寻找一个可以递归细分逼近最初模型的基网格,该算法在基模型容易获取的情况下能取到很好的效果,但是它会保持表面拓扑细节,因此对模型进行大规模简化的能力不足。
  • 去除(decimation)。去除方法迭代地去除网格上的顶点或者面片,并三角化每次去除后的空洞。这类方法比较简单,易于编程实现而且运行效率也较高,且通常保持原有的亏格,尤其适用于处理像共面多边形这种冗余的几何。
  • 顶点合并(vertex merging)。顶点合并一般将多个顶点合并成一个顶点,该算法也比较好实现,但是需要采用多种技术来确定哪些点被合并以及合并次序。
    有一个例子是边坍塌算法,将共边的两个顶点合并为一个点,该算法通常保持局部拓扑,但也允许修改拓扑。

细分

网格的细分和简化相反。对于一个给定的原始网格,通过网格细分产生更光滑的效果。细分广泛应用于电影行业,实际上算法提出者之一Catmull还是皮克斯和迪士尼的总裁。

下面是几个细分的例子:

一维细分,原本是4个点的线段,通过向中间插入点得到下一张图,不断迭代得到圆滑曲线。

三维网格细分,根据特定细分规则,每次细分每一个三角形被细分成4个小的三角形。

细分可以看做是一个两阶段过程,最初的网格被称为控制网格。

  1. 细化阶段,创建新的顶点并与先前顶点相连,产生新的更小的三角形
  2. 平滑阶段,计算新顶点的位置

这两步的细节决定了不同的细分方案,在第一步中一个三角形可以以不同的形式进行分割,第二部新顶点的位置可以以不同的方式插值产生。

Loop细分

Loop细分是第一个基于三角网格的细分方案。它更新每个已有的顶点,并对每条边创建一个新的顶点,这样每个三角形被分割成4个新的三角形。经过n步细分,一个三角形被分割成4n4n个三角形。

下图为一个loop细分的例子,新的顶点以黑色显示。

为了更好说明Loop细分的步骤

下图中左侧给出了第二个公式的相关点,右侧给出了第一个公式的相关点:

β是n的函数

√3细分

另外有一种细分方法,被称为3–√3细分。和Loop细分不同的地方在于,Loop把每个三角形划分成4个三角形,而3–√3细分把每个三角形细分成3个三角形。这意味着新增加的顶点在原三角形内部。不过,很明显内部点直接与各个点连线构成的三角形很奇怪,如下图中的第二张。而3–√3在连线之后,会做一个边翻转,把原来的边删掉,而连接新的顶点的作为边,像是把原来的边进行了一个翻转,如下图中最后一张:

Occupancy Networks: Learning 3D Reconstruction in Function Space

https://arxiv.org/abs/1812.03828

CVPR2019

code: https://github.com/autonomousvision/occupancy_networks

体素表示的缺点:内存随分辨率呈立方增加,故需要限制在32*32*32或64*64*64。使用例如八叉树的数据自适应表示来降低内存,实现起来又会复杂,现有数据自适应算法依旧局限于相对较小的256*256*256分辨率。

点云表示的缺点:由于缺少底层网格的连接结构,需要额外的后处理来从模型中提取三维几何图形。

网格表示的缺点:现有的网格表示通常基于对一个模板网格的变形,因此不允许任意拓扑。

点云和网格都限制了使用标准前馈网络能可靠预测的点/顶点的数量。

本文贡献:提出了基于对连续三维占据函数进行直接学习的三维重建新方法。利用神经网络gif.latex?f_%7B%5Ctheta%20%7D实现对任意分辨率的占据函数的预测。训练时大大降低了内存,推理时利用简单的多分辨率等值面提取算法从学习的模型中提取网格。

1、介绍了一种基于学习连续三维映射的对三维几何图形的新表示

2、展示了该表示如何用于从多种输入类型中重建三维几何形状

3、实验证明此方法能生成高质量网格且超越目前最优方法

本文提出了一种3D图形的表示方法,并给出了得到他的网络架构和训练方法。用decision boundary (判定边界)来表示物体的表面。这个方法贼好,放在2D类比,就像像素图和矢量图,矢量图是精度是无限的,但又不会耗费额外的内存。

随着深度神经网络的到来,基于学习的三维重建方法逐渐变得流行。但是和图像不同的是,在3D中没有规范的表示,既能高效地进行计算,又能有效地存储,同时还能表示任意拓扑的高分辨率几何图形。很多先进的基于学习的三维重建方法只能表示粗糙的三维几何,或者限制于一个特定的领域。在这篇论文中,作者提出了占用网格,一种新的基于学习的三维重建方法。占位网络隐式地将三维曲面表示为深度神经网络分类器的连续决策边界。与现有方法相比,该表示方式编码了高分辨率的3D输出,并且没有过多的内存占用。同时该方法能够高效地编码三维结构,并且能够从不同种类的输入推断出模型。实验证明,无论是在质量上还是在数量上,对于从单个图像、有噪声的点云和粗糙的离散体素网格进行三维重建,该方法都获得了具有竞争力的结果。

和传统多视图立体几何算法相比,学习模型的方法能够编码3D形状空间中的丰富先验信息,这有助于解决输入的模糊性。生成模型的方法在高分辨率的图像上已经取得了很好的效果,但是还没有复制到3D领域。与2D领域相比,暂时还没有就3D输出表示达成一致,这种表示既能提高内存效率,又能从数据中有效推断。现存的表示方法能够大概分成三类:体素、网格、点云,如下图所示:

体素表示是直接将像素一般化的情况,随着分辨率的提高,这种方法的内存占用将会呈指数增长,因此限制了分辨率。使用适当的损失函数,点云和网格被引入作为深度学习的代替表示。但是点云缺少底层网格的连接结构,从模型中提取3D几何需要额外的过程。现存网格的表示方法大多数是基于一个模板变形,因此不允许任意的拓扑结构。在这篇文章中,作者提出了一种基于直接学习连续三维占用函数的三维重建方法,如上图D所示。和其他方法不同的是,作者用神经网络预测了完全占用函数,它可以在任意分辨率下评估。这篇文章的主要贡献可以分为以下三点:1:介绍了一种基于学习连续三维映射的三维几何表示方法;2:使用此表示法重建各种输入类型的3D几何图形;3:此表示方法能够生成高质量的网格,并且达到先进技术水平。

相关工作

现有的基于学习的三维重建工作可以根据输出表示的不同分为基于体素的、基于点的和基于网格的三种。基于体素:由于其简单性,体素是鉴别和生成3D任务最常用的表示。早期的工作主要集中于使用3D卷积神经网络从一张图像重建三维几何,由于内存限制,分辨率不是很高,如果要达到相对较高的分辨率,需要牺牲网络架构或者减少每次输入的图片数量。其他的工作用体素表示来学习三维形状的生成模型,大多数的模型都是基于变分自动编码器或者生成对抗网络。为了提高分辨率,实现亚体素精度,一些研究人员提出预测截断符号距离字段(TSDF),其中3D网格中的每个点储存截断符号距离到最近的3D表面。然而,与占用表示相比,这种表示通常更难学习,因为网络必须推断出3D空间中的距离函数,而不是仅仅将体素分类为已占用或未占用。而且,这种表示方法的分辨率仍然受到内存的限制。基于点云:三维点云被广泛应用于机器人技术和计算机图形学领域,是一种非常引人注目的三维几何替代表示方法。Fan【1】引入点云作为三维重建的输出表示。然而,与其他表示不同的是,这种方法需要额外的后处理步骤来生成最终的3D网格。基于网格:网格首先被考虑用于区分三维分类或分割任务,在网格的顶点和边跨越的图上应用卷积,最近网格也被应用于三维重建的表示方法。不幸的是,大部分方法倾向于产生自交叉的网格,并且只能产生简单的拓扑结构。与上述方法相比,本文的方法产生了没有自相交的高分辨率封闭表面,并且不需要来自相同对象类的模板网格作为输入。并且使用深度学习来获得更有表现力的表示,可以自然地集成到端到端学习中。

具体一点,一个物体用一个occupancy function 来表示:

在这里插入图片描述

注意,是实数空间,不是离散的按一定分辨率取样的。
然后用一个神经网络来逼近这个函数,给每个实空间的3D点一个0-1之间的占用概率(因此和二分类模型等价)。神经网络 f 输入是一个点和一个几何体的表示(X),输出是一个0-1之间的实数,表示这个点在这个几何体里的概率。
而我们关注的是对象表面的决策边界。根据对物体的观察(如图像、点云等),当使用这样的网络对物体进行三维重建时,必须以输入作为条件。作者使用了下面的简单的功能对等:一个函数,它接受一个观察 x 作为输入,输出一个从点p到R的函数,这可以通过一个函数等价描述:一对(p, x)作为输入和输出一个实数。后一种表示可以用一个神经网络参数化,该神经网络以一对(p,x)作为输入,输出一个表示占用概率的实数:

对不同输入类型的数据,用不同encoder来输入。
单个图像:ResNet
体素:3D CNN
点云:PointNet等

在这里插入图片描述

这就是占用网络。2训练:为了学习神经网络的参数,考虑在对象的三维边界体中随机采样点,对于第i个样本,采样K个点,然后评估这些位置的小批量损失Lb如下所示:

其中xi是B批次的第i个观测值,Oij是点云的真实位置,L是交叉熵损失。该方法的性能取决于用于绘制用于训练的pij位置的采样方案,将在后面详细讨论。这个三维表示方法也可以用于学习概率潜在变量模型,定义损失函数如下:

3推论:为了提取一个新的观测值对应的等值面,作者引入了多分辨率等值面提取算法(MISE),如下图所示。

多分辨率等值面提取(MISE):①以初始分辨率离散化体积空间,给网格中的所有p用网络来评估占据。将大于或等于某阈值的所有网格点p标记为占据(红色圆形),非占据(青色菱形)。阈值是超参数,决定提取的三维表面的厚度。确定所有既含占据又含非占据顶角的体素并标记为动态(红色),如果在当前分辨率应用MC算法,这些是会使网格自相交的体素,将每个动态体素细分成8个子体素;②评估所有由这样细分而引入到占据网格的新的网格点(空心圈)。重复①②直到达到最终目标分辨率。在最终分辨率,利用MC算法提取网格,利用一阶和二阶梯度信息简化和细化输出网格。

首先在给定的分辨率上标记所有已经被评估为被占据(红色圆圈)或未被占据(青色方块)的点。然后确定所有的体素已经占领和未占领的角落,并标记(淡红色),细分为4个亚体素。接下来,评估所有由细分引入的新网格点(空圆)。重复前两个步骤,直到达到所需的输出分辨率。最后使用marching cubes算法【2】提取网格,利用一阶和二阶梯度信息对输出网格进行简化和细化。如果初始分辨率的占用网格包含网格内外各连通部分的点,则算法收敛于正确的网格。因此,采取足够高的初始分辨率来满足这一条件是很重要的。实际上,作者发现在几乎所有情况下,初始分辨率为32的三次方就足够了。通过marching cubes算法提取的初始网格可以进一步细化。在第一步中,使用Fast-Quadric-Mesh-Simplification算法【3】来简化网格。最后,使用一阶和二阶(即梯度)的信息。为了达到这个目标,作者从输出网格的每个面抽取随机点pk进行采样,并将损失最小化:

其中n(pk)为网格在pk处的法向量。4相关细节:作者使用具有5个ResNet块的全连接神经网络实现了占用网络,并使用条件批处理归一化对输入进行条件设置。根据输入的类型使用不同的编码器架构。对于单视图3D重建,使用ResNet18架构。对于点云,使用PointNet编码器。对于体素化输入,使用3D卷积神经网络。对于无条件网格生成,使用PointNet作为编码器网络。更多细节见原文。注:在我看来,这是一个端到端的网络,可以理解成一个GAN网络。前面的全连接神经网络编码输入的图像,预测每一个点被占用的概率,即该3D点是处于模型内部还是在模型的外面。通过采样多个点,我们就可以得到一个决策边界,这个边界就可以近似的理解成模型的外壳,然后通过后面的算法获得更高分辨率的模型。

结果展示:

连续表示(右)和不同分辨率下的体素化(左)的定性比较
上图显示了连续表示(纯橙色线)和网格体素化(蓝线)的IoU,以及两个表示(虚线)所需的每个模型的参数数量。
单幅图像三维重建,输入图像显示在第一列中,其他列显示与不同baselines相比该方法的结果。
真实数据的重建结果

基于点云的三维重建结果比较:

特斯拉 – occupancy network占据网络

视频: https://www.zhihu.com/zvideo/1566362268736200704?playTime=194.2

讲解: https://zhuanlan.zhihu.com/p/572057070

今年Tesla FSD部分,感知网络从去年的Bev感知(Hydranet)的基础上,更近一步,提出了occupancy network.

1. 为什么是occupancy network?

在基于 LiDAR 的系统中,可以根据检测到的反射强度来确定对象的存在,但在相机系统中,必须首先使用神经网络检测对象。如果看到不属于数据集的对象怎么办?比如侧翻的大卡车。仅此一项,就引发了很多事故。

可行驶区域的一些问题

rv、bev (Birds Eye View) 空间下可行驶区域会有一定问题:

  • 地平线的深度不一致,只有2个左右的像素决定了一个大区域的深度。
  • 无法看穿遮挡物,也无法行驶。
  • 提供的结构是 2D的,但世界是 3D 的。
  • 高度方向可能只有一个障碍物(悬垂的检测不到),目前是每类对象设置固定的矩形。
  • 存在未知物体,例如,如果看到不属于数据集的对象。

所以希望有种通用的方式来解决该问题,首先能想到的是bev下的可行驶区域,但相对来说在高度维会比较受限,索性一步到位变成3d空间预测、重建。

2. Occupancy Network

2022 CVPR中,tesla FSD新负责人 Ashok Elluswamy 推出了Occupancy Network。借鉴了机器人领域常用的思想,基于occupancy grid mapping,是一种简单形式的在线3d重建。将世界划分为一系列网格单元,然后定义哪个单元被占用,哪个单元是空闲的。通过预测3d空间中的占据概率来获得一种简单的3维空间表示。关键词是3D、使用占据概率而非检测、多视角。

Occupancy Network

这里输出的并非是对象的确切形状,而是一个近似值,可以理解为因为算力和内存有限,导致轮廓不够sharp,但也够用。另外还可以在静态和动态对象之间进行预测,以超过 100 FPS 的速度运行(或者是相机可以产生的 3 倍以上)。

2020 AI day中的Hydranet算法中有三个核心词汇:鸟瞰图(BEV)空间、固定矩形、物体检测。而occupancy network针对这三点有哪些优化,可以看:

第一是鸟瞰图。在 2020 年特斯拉 AI 日上,Andrej Karpathy 介绍了特斯拉的鸟瞰网络。该网络展示了如何将检测到的物体、可驾驶空间和其他物体放入 2D 鸟瞰视图中。occupancy则是计算占据空间的概率。

BEV vs Volume Occupancy

最主要的区别就是,前者是 2D表示,而后者是3D表示。

第二是固定矩形,在设计感知系统时,经常会将检测与固定输出尺寸联系起来,矩形无法表示一些异形的车辆或者障碍物。如果您看到一辆卡车,将在featuremap上放置一个 7×3 的矩形,如果看到一个行人,则使用一个 1×1 的矩形。问题是,这样无法预测悬垂的障碍物。如果汽车顶部有梯子,卡车有侧拖车或手臂;那么这种固定的矩形可能无法检测到目标。而使用Occupancy Network的话,看到下图中,是可以精细的预测到这些情况的。

固定矩形 vs Volume Occupancy

后者的工作方式如下:

  1. 将世界划分为微小(或超微小)的立方体或体素
  2. 预测每个体素是空闲还是被占用
体素空间中的被占用体素

这里意味着两种方法的思维方式完全不一样,前者是为一个对象分配一个固定大小的矩形,而后者是简单地说“这个小立方体中有一个对象吗? ”。

第三点,物体检测。

目前有很多新提出来的物体检测算法,但大多面向的是固定的数据集,只检测属于数据集的部分或全部对象,一旦有没有标注的物体出现,比如侧翻的白色大卡车,垃圾桶出现的路中,这是没法检测到的。而当思考和训练一个模型来预测“这个空间是空闲的还是被占用的,不管对象的类别是什么?”,正可以避免这种问题。

对象检测 vs Occupancy Network

基于视觉的系统有 5 个主要缺陷:地平线深度不一致物体形状固定静态和移动物体遮挡本体裂缝。特斯拉旨在创建一种算法来解决这些问题。

新的占用网络通过实施 3 个核心思想解决了这些问题:体积鸟瞰图、占用检测体素分类。这些网络可以以超过 100 FPS 的速度运行,可以理解移动对象和静态对象,并且具有超强的内存效率。

模型结构:

cvpr 时的网络结构

  • 输入为不同视角的图像(总共 8 个:正面、侧面、背面等……)。
  • 图像由RegnetBiFPN等网络提取特征
  • 接着transformer模块,使用注意力模块,采用位置图像编码加上QKV获得特征,以此来产生占用Occupancy。
  • 这会产生一个Occupancy feature,然后将其与之前的体积(t-1、t-2 等)融合,以获得4D Occupancy feature
  • 最后,我们使用反卷积来检索原始大小并获得两个输出:Occupancy volume和Occupancy flow。

AI day时的网络结构

相比cvpr时,AI day上的分享更加详细,主要有三点更新:

  1. 最左侧是基于photon count的传感器图像作为模型输入(虽然鼓吹的很高大上,其实就是ISP处理前的raw数据),这里的好处是可以在低光照、可见度低等情况下,感知的动态范围更好。
  2. temporal alignment利用里程计信息,对前面时刻的occupancy features进行时序上的加权融合,不同的时间的特征有着不同的权重,然后时序信息似乎实在Channel维度进行拼接的?组合后的特征进入deconv模块提高分辨率。这样看来时序融合上,更倾向于使用类似transformer或者时间维度作为一个channel的时序cnn进行并行的处理,而非spatial RNN方案。
  3. 相比CVPR的方案,除了输出3D occupancy特征和occupancy flow(速度,加速度)以外,还增加了基于x,y,z坐标的query思路(借鉴了Nerf),可以给occupancy network提供基于query的亚像素、变分辨率的几何和语义输出。

因为nerf只能离线重建,输出的occupancy 猜想可以通过提前训好的的nerf生成GT来监督?

光流估计和Occupancy flow

特斯拉在这里实际上做的是预测光流。在计算机视觉中,光流是像素从一帧到另一帧的移动量。输出通常是flow map 。

在这种情况下,可以有每一个体素的流动,因此每辆车的运动都可以知道;这对于遮挡非常有帮助,但对于预测、规划等其他问题也很有帮助

Occupancy Flow(来源

Occupancy flow实际上显示了每个对象的方向:红色:向前 — 蓝色:向后 — 灰色:静止等……(实际上有一个色轮代表每个可能的方向)

Nerf

特斯拉的 NeRF(来源

神经辐射场,或 Nerf,最近席卷了3D 重建;特斯拉也是其忠实粉丝。它最初的想法是从多视图图像中重建场景(详见3D 重建课程)。

这与occupancy network 非常相似,但这里的不同之处在于也是从多个位置执行此操作的。在建筑物周围行驶,并重建建筑物。这可以使用一辆汽车或特斯拉车队在城镇周围行驶来完成。

这些 NeRF 是如何使用的?

由于Occupancy network产生 3D volume,可以将这些 3D volume与 3D-reconstruction volume(Nerf离线训练得到)进行比较,从而比较预测的 3D 场景是否与“地图”匹配(NeRF 产生 3D重建)。

在这些重建过程中也可能出现问题是图像模糊、雨、雾等……为了解决这个问题,他们使用车队平均(每次车辆看到场景,它都会更新全局 3D 重建场景)和描述符而不是纯像素。

使用Nerf的descriptor

这就是获得最终输出的方式!特斯拉还宣布了一种名为隐式网络的新型网络,其主要思想是相似的:通过判断视图是否被占用来避免冲突

总结来说:

  1. 当前仅基于视觉的系统的算法存在问题:它们不连续,在遮挡方面做得不好,无法判断物体是移动还是静止,并且它们依赖于物体检测。 因此,特斯拉决定发明“Occupancy network”,它可以判断 3D 空间中的一个单元格是否被占用。
  2. 这些网络改进了 3 个主要方面:鸟瞰图、物体类别和固定大小的矩形。
  3. occupancy network分 4 个步骤工作:特征提取、注意和occupancy检测、多帧对齐和反卷积,从而预测光流估计和占用估计。
  4. 生成 3D 体积后,使用 NeRF(神经辐射场)将输出与经过训练的 3D 重建场景进行比较。
  5. 车队平均采集数据用于解决遮挡、模糊、天气等场景

reference:

Marching Cubes 算法

 Marching Cubes算法是三维离散数据场中提取等值面的经典算法,其主要应用于医学领域的可视化场景,例如CT扫描和MRI扫描的3D重建等。

Marching Cube 首先将空间分成众多的六面体网格,类似将空间分成很多的小块

我们有很多的已知采样点,并且知道这些点在空间中的空间场值,现在我们将空间分为很多个小格子,每个小格子都有8个顶点,我们通过计算8个顶点周围(范围与六面体的大小相关)的采样点,近似计算出8个顶点的空间场值(加权评价等方法)。 

以0等值面为例:如何找到0等值面经过的六面体网格? 

算法主要的思想是在三维离散数据场中通过线性插值来逼近等值面,具体如下:三维离散数据场中每个栅格单元作为一个体素,体素的每个顶点都存在对应的标量值。如果体素顶点上的值大于或等于等值面值,则定义该顶点位于等值面之外,标记为“0”;而如果体素顶点上的值小于等值面值,则定义该顶点位于等值面之内,标记为“1”。由于每个体素单元有8个顶点,那么共存在2^8 = 256种情形,下图是Marching Cubes算法的15种基本情形,其他241种情形可以通过这15种基本情形的旋转、映射等方式实现。

 每个体素单元上顶点和边的索引规则如下图左所示,假如体素下方的顶点3的值小于等值面值,其他顶点上的值都大于等值面值(如下图右所示),那么我们可以生成一个与体素边2,3,11相交的三角面片,而三角面片顶点的具体位置则需要根据等值面值和边顶点3-2,3-0,3-7的值线性插值计算得到。

对于与等值面存在交点的体素边,交点坐标用P表示,P1、P2代表边上两个端点的坐标,V1、V2代表这两个端点上的值,V代表等值面值,那么交点坐标的计算公式如下:

P = P1 + (V – V1)·(P2 – P1)/(V2 – V1)

  算法第一步:通过edgeTable表判断等值面和体素单元哪一条边相交

  体素单元顶点状态的索引号定义规则如下:

cubeindex = 0;
if (V[0] < isolevel) cubeindex |= 1;
if (V[1] < isolevel) cubeindex |= 2;
if (V[2] < isolevel) cubeindex |= 4;
if (V[3] < isolevel) cubeindex |= 8;
if (V[4] < isolevel) cubeindex |= 16;
if (V[5] < isolevel) cubeindex |= 32;
if (V[6] < isolevel) cubeindex |= 64;
if (V[7] < isolevel) cubeindex |= 128;

以上图所示为例,仅顶点3标记为“1”,其他顶点标记为“0”,那么体素单元的顶点状态为0000 1000或者8,通过查找表得到edgeTable[8] = 1000 0000 1100,意味着体素单元的边2,3,11和等值面相交,然后通过线性插值计算各个交点的位置。

算法第二步:通过triTable表生成对应三角面片的组成情况

  还是以上图所示为例,通过查找表得到triTable[8] = {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},意味着该种顶点状态可以生成三角面片(3, 11, 2),代表三角面片的3个顶点为边3,11,2和等值面相交的交点。

  经过上述步骤之后,我们可以得到等值面的点面信息。为了进一步完善显示效果,需要调整顶点法向。假设顶点(i, j, k)上的值为f(i, j, k),采用中心差分方法可以计算该点处的梯度矢量:

对G进行归一化,得到顶点(i, j, k)上的单位法向量,然后对体素单元上8个顶点的法向量进行线性插值就可得到三角面片各个顶点的显示法向量。

参考:http://graphics.stanford.edu/~mdfisher/MarchingCubes.html

Marching Cube的问题

当然最初的Marching Cube 有很多问题,例如拓扑连接二义性,一种状态可以有多种连接关系

而且Marching Cube的效率不是特别高,需要借助分层结构和并行计算。
而且Marching Cube生成面片的大小与六面体的大小相关,过大则会导致模型模糊,细节消失,过小会导致面片的数目过多。

但是从1987年提出Marching Cube至今,已经对其有了很多的改进和优化算法,在处理时间,减少内存开销,分辨率方面都有很大的优化。

ICCV2021|极大似然法做点云降噪

论文标题:Score-Based Point Cloud Denoising

论文链接:https://arxiv.org/abs/2107.10981

作者单位:北京大学

本文提出了一种新的点云去噪范式,利用噪声点云的分布模型并利用分布的分数,表现SOTA!性能优于DMR、GPDNet等网络。

从扫描设备获取的点云通常会受到噪声的干扰,这会影响表面重建和分析等下游任务。噪声点云的分布可以看作是一组无噪声样本 p(x) 与某个噪声模型 n 卷积的分布,导致 (p∗n)(x) 的模式是底层清洁表面。为了对嘈杂的点云去噪,我们建议通过梯度上升从 p∗n 增加每个点的对数似然——迭代更新每个点的位置。由于 p∗n 在测试时是未知的,我们只需要分数(即对数概率函数的梯度)来执行梯度上升,我们提出了一种神经网络架构来估计 p∗n 的分数只给定嘈杂的点云作为输入。我们推导出用于训练网络的目标函数,并利用估计的分数开发去噪算法。实验表明,所提出的模型在各种噪声模型下优于最先进的方法,并显示出应用于其他任务(如点云上采样)的潜力。

VirtualCube: An Immersive 3D Video Communication System

3D视频会议系统VirtualCube:相隔万里也如近在咫尺般身临其境

https://www.microsoft.com/en-us/research/project/virtualcube/

微软亚洲研究院的研究项目 3D 视频会议系统 VirtualCube,可以让在线会议的与会者建立自然的眼神交互,沉浸式的体验就像在同一个房间内面对面交流一样。该技术的相关论文被全球虚拟现实学术会议 IEEE Virtual Reality 2022 接收并获得了大会的最佳论文奖(Best Paper Award – Journal Papers Track)。

在日常交谈中,相互注视和摆动头部等动作都是自然对话的组成部分,尤其是当我们在面对面交流中变换话题、控制发言或转换交流对象时,都会伴随眼神和肢体动作的交流。然而,当前的视频会议技术却存在着一定的缺陷——由于摄像头和屏幕不在同一高度,如果看向屏幕眼神往往很不自然,如果看向摄像头则无法关注到其他与会者的反应,因此视频会议缺少了线下交流的真实感和互动感。而且在实际的工作中,我们还会有各种不同的会议场景,比如多人会议、同排而坐协同工作等情况,对于捕捉与会者的侧方视线和动作来说,现有的视频会议系统就更无能为力了。

如果有一个会议系统,可以让人们即使身处不同的地方,也能像在同一房间里一样交流,视线转动就能与同伴建立起眼神沟通,这是否会给远程办公增添一份沉浸式的真实感呢?

利用现有的普通硬件设备搭建的 3D 视频系统:

为了解决这些问题,微软亚洲研究院提出了创新的 3D 视频会议系统——VirtualCube,它可以在远程视频会议中建立起真人等大的 3D 形象,无论是正面沟通,还是侧方交流,系统都能够正确捕捉到与会者的眼神、动态,建立起眼神和肢体交流。相关论文被全球虚拟现实学术会议 IEEE Virtual Reality 2022 接收并获得了大会的最佳论文奖(Best Paper Award – Journal Papers Track)

VirtualCube 系统具有三大优势:

标准化、简单化,全部使用现有的普通硬件设备。与办公场所中常见的格子间(Cubicle)类似,每个 VirtualCube 都提供了一致的物理环境和设备配置:与会者正前方安装有6个 Azure Kinect RGBD 摄像头,以捕捉真人的图像和眼神等动作;在与会者的正面和左右两侧还各有一个大尺寸的显示屏,以创造出身临其境的参会感。使用现有的、标准化的硬件能够大大简化用户设备校准的工作量,从而实现 3D 视频系统的快速部署和应用。

感。使用现有的、标准化的硬件能够大大简化用户设备校准的工作量,从而实现 3D 视频系统的快速部署和应用。

6个 Azure Kinect RGBD 摄像头捕捉人像和眼神等动作

多人、多场景,任意组合。作为在线视频会议的基础构建,VirtualCube 的虚拟会议环境可由多个空间(Cube)按照不同的布局组成,以支持不同的会议场景,例如两人的面对面会议、两人并排会议,以及多人的圆桌会议等。

多个空间(Cube)可实现任意组合

实时、高质量渲染真人图像。VirtualCube 可以捕捉到参与者的各种细微变化,包括人的皮肤颜色、纹理,面部或衣服上的反射光泽等,并实时渲染生成真人大小的 3D 形象,显示在远程与会者的屏幕中。而且虚拟会议环境的背景也可以根据用户的需求自由选择。

任意变换会议场景,都能身临其境

V-Cube View和V-Cube Assembly算法双剑合璧,沉浸式会议体验不再是难题

其实业界对 3D 视频会议的研究从未间断过。早在2000年,就有人曾提出过与类似混合现实技术有关的畅想。基于这个设想,科研人员一直在探索如何将视频会议以更逼真、更自然的方式呈现,期间也出现了不同的技术路线和解决方案,但都没有达到理想的效果。对此,微软亚洲研究院主管研究员张译中和杨蛟龙表示,过往的研究仍然有很多没有解决的问题:首先,在真实环境下,无论放置怎样的单目摄像设备,即使图像质量再高,与会者也很难形成自然的眼神交流,特别是多人会议的情况;其次,很多研究针对特定的会议场景进行优化,如两个人面对面的会议或三人的圆桌会议,很难支持不同的会议设置;第三,虽然在影视界我们能够看到一些逼真的虚拟人,但那是需要专业的技术和影视团队长时间打磨和优化才能实现的,仍然需要一定的手工劳动,目前无法进行实时捕捉和实时渲染。

为此,微软亚洲研究院提出了 V-Cube View 和 V-Cube Assembly 两大全新算法,在 VirtualCube 中实现了自动捕捉参与者的手势动作和眼神变化,实时渲染形成高保真图像,让参与者在虚拟会议中体验到真实会议的氛围。

“两个人在交谈且相互注视对方时,对方看到的自己就相当于在自己眼睛的位置放置一个摄像头。但屏幕和摄像头的位置存在高低差,所以当一方注视屏幕中对方的眼睛时,摄像头捕捉到的眼神就会偏离。因此在 VirtualCube 中,我们在与会者正前方的屏幕边缘放置了六个摄像头,通过 V-Cube View 算法合成正确的视点图像,并利用 V-Cube Assembly 确定正确的相对位置,进而给与会者一个沉浸式的会议体验”,张译中介绍道。

基于深度学习的 V-Cube View 算法,通过 VirtualCube 中的六个摄像头的 RGBD 图像作为输入,实时渲染任意目标视点下人的高保真视频。这里的技术挑战是如何同时做到高保真和实时。对此,微软亚洲研究院主管研究员杨蛟龙解释道:“实时渲染高保真的人像,特别是高保真的人脸一直是个具有挑战性的研究课题。传统的三维重建和纹理贴图的做法虽然可以做到实时绘制,却无法重现出真实人脸复杂的材质和在不同视点下外观的变化。为此我们提出了一种新的 Lumi-Net 渲染方法,其核心思想是利用重构的三维几何作为参考来实现一个四维光场的实时渲染,并结合神经网络进行图像增强,从而提高了渲染的质量,特别是人脸区域的高保真度。”

具体而言,V-Cube View 算法分为三步进行。首先,研究员设计了一个神经网络来快速求解目标视点深度图作为人体的几何参考(geometry proxy)。然后,算法在给定的几何参考下将获取的多视角 RGB 图像(即光线)进行融合,实现绘制。在这一步中,研究员受传统的非结构化流明图(Unstructured Lumigraph)方法启发,将输入光线与目标像素光线的方向和深度差异作为先验,通过神经网络学习最合适的融合权重。最后,为了进一步提升绘制质量,研究员们使用了神经网络对上一步的绘制结果进行图像增强。整个算法实现了端到端的训练,并在训练过程中引入了感知损失函数及对抗学习技术,使得算法可以自动学习出最优的神经网络,实现高保真的绘制。而且为了保证绘制的实时性,算法的前两步都在低分辨率图像上执行,这样可以在不损失太多精度的情况下大大降低所需计算量。经过精心设计和优化的 V-Cube View 算法,将实时的三维人物渲染质量提升到了一个新的高度。

V-Cube View 算法示意图

另外,为了让 VirtualCube 的使用者拥有和线下交流同样的体验,在将与会者映射到虚拟环境时,系统还要考虑他们之间的相对位置关系,这时 V-Cube Assembly 算法就发挥了重要的作用。“在整个虚拟会议环境中,V-Cube Assembly 可以被定义为全局坐标系统,单个的 VirtualCube 则为局部坐标系统。全局坐标系与局部坐标系之间的正确 3D 几何变化,对在视频显示器上正确呈现远程与会者的图像至关重要”杨蛟龙介绍。

研究员们首先会在 VirtualCube 中捕捉与会者的 3D 几何体,形成局部坐标系,然后将这些局部坐标系的 3D 几何体数据,投射到全局坐标系,经过 V-Cube Assembly 处理,在全局虚拟会议环境中确定每个 VirtualCube 参与者正确的相对位置,最后再将全局 3D 几何体转换为 VirtualCube 的局部坐标系,影射到 VirtualCube 的屏幕上。

V-Cube Assembly 算法示意图

抛砖引玉,畅想未来办公无限可能

VirtualCube 给 3D 视频会议系统提供了一种全新的思路。无论从算法设计、端到端设备部署还是工程调试上,VirtualCube 都证明了利用现有的普通硬件设备就可以实现沉浸式的 3D 视频会议体验。

除了让与会者“共享”同一个物理空间外,研究员们还在探索利用 VirtualCube 系统满足远程办公中的更多协作需求。例如,研究员们展示了这样一种场景:在协同工作时,两位与会者及其电脑桌面都将是视频会议的一部分,因此与会者并排而坐,并且跨屏幕传递自己桌面上的文档和应用程序会让远程协作更加方便。

随着技术的不断精进,未来,大家或许都可以实现身隔万里,却能亲临其境一起办公,自然沟通的遥在体验,而这将极大地提高混合办公的效率。微软亚洲研究院的研究员们也希望 VirtualCube 可以成为一颗探索的种子,给更多研究人员带来启发,在大家共同的努力下,找到更好的虚拟空间交互形式,打开未来办公的更多可能。

PointCLIP 用CLIP巧解点云分类

论文: CVPR2022 PointCLIP: Point Cloud Understanding by CLIP

代码:https://github.com/ZrrSkywalker

本文提出PointCLIP:第一个将 CLIP 应用于点云识别的工作,它将2D预训练的知识迁移到3D领域,可在没有任何 3D 训练的情况下对点云进行跨模态零样本识别。

在本文中,我们通过提出 PointCLIP 来确定这种设置是可行的,它在 CLIP 编码的点云和 3D 类别文本之间进行对齐。

因为重新训练clip的代价太大(原始clip的训练数据 有4yi对文本图像对),因此没法去修改clip的模型结构,因此也就意味之模型的输入:text-image形式。因此作者将三d点云数据经过不同视角的渲染,变成M个RGB的二维maps,送如encoder中并获得M个特征,通过与对应的文本特征做一个相似度,来确定 当前的点云类别。

模型结构

具体来说,我们通过将点云投影到多视图深度图中而不进行渲染来编码点云,并聚合视图方式的零样本预测以实现从 2D 到 3D 的知识迁移。最重要的是,我们设计了一个视图间适配器,以更好地提取全局特征,并将从 3D 中学到的小样本知识自适应地融合到 2D 中预训练的 CLIP 中。

通过在小样本设置中微调轻量级适配器,PointCLIP 的性能可以大大提高。此外,我们观察到 PointCLIP 和经典 3D 监督网络之间的互补特性。通过简单的集成,PointCLIP 提高了基线的性能,甚至超越了最先进的模型。因此,PointCLIP 是在低资源成本和数据机制下通过 CLIP 进行有效 3D 点云理解的有前途的替代方案。

ensembling聚合部分:可以认为是把pointclip作为一个即插即用的模块,用于辅助3D点云分类网络做分类任务 。

实验结果

我们对广泛采用的 ModelNet10、ModelNet40 和具有挑战性的 ScanObjectNN 进行了彻底的实验,以证明 PointCLIP 的有效性。

NeRF:类神经网路在View Synthesis的热门新方向

项目主页:https://www.matthewtancik.com/nerf

论文地址: https://arxiv.org/abs/2003.08934  
code:https://github.com/bmild/nerf https://github.com/yenchenlin/nerf-pytorch
ECCV 2020 (Oral Presentation, Best Paper Honorable Mention)

NeRF:用深度学习完成3D渲染任务的蹿红

文章难度:★★★★☆
阅读建议: 这篇文章尽量深入浅出地介绍 NeRF,这个近期 deep learning的热门新宠儿。 NeRF因为牵扯到许多 rendering与机率的设计,所以直接啃起来是挺硬的。这篇文章一开始会先简单地介绍 NeRF以及 Volume Rendering的概念,而后才会一步一步地解释 NeRF的运作细节与训练方法。最后也会简单带过几个接续 NeRF研究的优秀方法。
推荐背景知识: deep learning, multilayer perceptron (MLP), volume rendering, ray tracing, light field, view synthesis, neural rendering, quadrature, stratified sampling.

NeRF 是 2020 年 ECCV 上获得最佳论文荣誉提名的工作,其影响力是十分巨大的。NeRF 将隐式表达推上了一个新的高度,仅用 2D 的 posed images 作为监督,即可表示复杂的三维场景,在新视角合成这一任务上的表现是非常 impressive 的。

问题1:3D渲染是要干什么?

用照相机拍照是一个现实世界的物理过程,主要是光学过程,拍照对象是现实世界中真实的万事万物,形成照片的机制主要就是:光经过镜头,到达传感器,被记录下来。

渲染就是用计算机模拟这一过程,模拟“拍照”的对象是已存在的某种三维场景表示(3D representation of the scene),模拟生成照片的机制是图形学研究人员精心设计的算法。

关键前提:渲染的前提是某种三维场景表示已经存在。渲染一词本身不包办生成三维场景表示。不过,渲染的确与三维场景表示的形式息息相关;因此研究渲染的工作通常包含对三维场景表示的探讨。

  • 问题2:3D渲染是图形学问题,那么原先大家是用什么传统图形学方法实现3D渲染的呢?

主要有两种算法:光栅化(rasterization),光线追踪(ray tracing);都是对照相机拍照的光学过程进行数学物理建模来实现的

Quick Overview: Neural Radiance Fields (NeRF)

NeRF的核心精神是将物体与场景的信息,编码 (encode) 进 MLP (multi-layer perceptron)中。然后使用 computer graphics(计算机图形学)中的 volume rendering(立体渲染)将 MLP中的信息投影出来。

在训练的部分, NeRF 所需要的是某个物体与场景的 multi-view多视角影像,利用这些影像来训练NeRF,或者更直接地说,将信息 encode进 NeRF。之后就可以对这个物体与场景 render出连续、不存在于原始信息的视角

NeRF整体的结果非常令人惊艳,特别是在金属或有光泽物体的结果,视觉的真实性真的非常高。可以参考以下的图片,或者直接到官方的页面看影片会更有感觉。

不过如果对于没有 rendering相关知识的人,要直接理解NeRF可能会有点障碍。因此,接下来会先简单带一些基础的 volume rendering与 ray tracing观念,再回头去看 NeRF到底是怎么做的。

Volume Rendering

所谓的 volume rendering (立体渲染) 指的是将 discretely sampled 3D data投影到 2D的技术。像是以下这张图片,我们已知一个物体的离散3D信息,对于目前的视角,就可以动态地渲染出这个视角看到的画面。

使用shear warp algorithm做volume rendering的例子。(资料来源)

Ray Tracing

而在 rendering上其中一个实作方法是 ray tracing。 这个方法可以用眼睛看物体来解释。我们眼睛之所以看的到物体,是因为有光源打到了物体,然后反射进我们的眼睛。而Ray tracing的想法其实就是反推这个射线 (ray),从相机中心发出射线,与物体相交就根据规则反射、折射或吸收,直到遇到光源或者走太远停住。

Ray tracing的方法示意图 (资料来源)

总之, ray tracing就是借由这个概念算出在 image平面上的 2D投影该长什么样子。实际上这边的名词蛮复杂的 (至少对非图学出身的笔者来说),像是 ray tracing、 ray casting、 ray marching什么的。为了避免混淆视听,这边就先不解释过多了。

接下来,就开始正式介绍 NeRF的细节。

Neural Radiance Fields (NeRF)-神经辐射场

NeRF网路的输入是一组 5D的参数,包含一组 3D的 location X = (x, y, z)跟一组 2D的 view direction (θ, φ),实事上这个 view direction表示为 3D Cartesian unit vector(笛卡尔单位矢量),称为 d。而NeRF网路的输出则是一组 emitted color (如RPG的c=(r, g, b)) 与 volume density σ

以下图来解释会更加清楚。这个 3D location指的是在 3D空间中的任何一个点,比如说怪手的尖端,而 view direction则是说我要从哪个视角看。NeRF网路的输出则是这个 3D点实际 (或者说推估) 的颜色,以及推估的 volume density(体积密度σ:可以简单理解为不透明度)。

有了RGB和体密度3D物体表示,就可以使用 Ray Tracing 等3D渲染方法来渲染出任意视角的2D投影。(Volume rendering)

NeRF的运作概念。(资料来源)

Radiance Fields,或者说映射 gθ ,能对三维场景进行隐式表示(implicit scene representation)。在上一节,我们说过某种三维场景表示正是渲染的前提。实现渲染也是 作者提出Radiance Fields这一新型三维场景表示方法 的目的所在。

NEeRF输入数据准备(将一系列的2d图片转成网络所需的输入):

多视角2D图像准备

想要利用NeRF拟合自己拍摄的3D场景,首先需要准备多张从不同角度拍摄的同场景静态2D图像,以沙发为例。

沙发多视图

相机内外参估计

不过仅仅有2D多视图还不够,在重建阶段,我们还需要各个点的位置 x={x,y,z} 和方位 d={θ,ϕ} 作为输入进行重建。为了获得这些数据,NeRF中采用了传统方法COLMAP进行参数估计。还是以沙发为例,通过COLMAP可以得到场景的稀疏重建结果,其输出文件包括相机内参,相机外参和3D点的信息,然后进一步利用LLFF开源代码中的imgs2poses文件将内外参整合到一个文件poses_boudns.npy中,该文件记录了相机的内参,包括图片分辨率(图片高与宽度)、焦距,共3个维度、外参(包括相机坐标到世界坐标转换的平移矩阵 t 与旋转矩阵 R,其中旋转矩阵为 R∈R3×3 的矩阵,共9个维度,平移矩阵为 t∈R3×1 的矩阵,3个维度,因此该文件中的数据维度为 N×17 (另有两个维度为光线的始发深度与终止深度,通过COLMAP输出的3D点位置计算得到),其中N为图片样本数。

ps: 这里建议将nerf-pytorch中加载poses_boudns.npy数据中的代码与imgs2poses中保存poses_boudns.npy的代码对着看一遍,就可以理解加载时为什么要搞一些奇怪的维度变换等操作了。

DCOLMAP重建结果

Raw数据到MPL的输入

输入生成与坐标系变换

在理解NeRF的过程中涉及到一个很重要的问题,即原文中提到的MLP的输入 x={x,y,z} 和 d={θ,ϕ} 是什么,其与相机内外参有什么关系?要搞懂这个问题,需要先理解坐标系变换

总的来说,坐标变换的目的在于将不同视角下视角特定的坐标系投影到一个统一的世界坐标中进行三维重建,见get_rays_np函数。首先,我们在像素坐标下进行网格点采样,得到特定分辨率图像的各个像素点坐标

i, j=np.meshgrid(np.arange(W, dtype=np.float32), np.arange(H, dtype=np.float32), indexing='xy')

然后,我们进行像素坐标到相机坐标的变换,要理解这个变换需要清楚两个点。

dirs=np.stack([(i-K[0][2])/K[0][0], -(j-K[1][2])/K[1][1], -np.ones_like(i)], -1)

首先像素坐标到相机坐标的变换属于投影变换的逆变换,即2D点到3D的变化,即我们需要根据像素点的坐标 (u,v) 计算该点在相机坐标系下的三维的坐标 (X,Y,Z)。

像素坐标到相机坐标

这时帅气的小伙伴就发现了,为什么相机坐标的 Y 和 Z 前面有负号?那是因为COLMAP采用的是opencv定义的相机坐标系统,其中x轴向右,y轴向下,z轴向内;而Nerf pytorch采用的是OpenGL定义的相机坐标系统,其中x轴向右,y轴向上,z轴向外。因此需要在y与z轴进行相反数转换。

最后,我们进行相机坐标到世界坐标的转换得到光线始发点与方向向量,这里需要了解世界坐标到相机坐标的变换过程,本质上为矩阵相乘,要进行反向变化只需要对变化矩阵求逆即可(COLMAP原输出的是世界坐标到相机坐标的旋转矩阵,在LLFF的imgs2poses.py中已经进行了求逆操作)。

rays_d=np.sum(dirs[..., np.newaxis, :] *c2w[:3,:3], -1)
rays_o=np.broadcast_to(c2w[:3,-1], np.shape(rays_d))

首先因为相机坐标与世界坐标的坐标原点不一致,要解决这个问题只需要将相机坐标进行平移变化即可进行对齐,实现平移的方式在是世界坐标系下减去一个平移矩阵,即相机外参中的平移矩阵 t ,对应得到代码中的rays_o。

平移以对齐坐标系的原点

此外,由于相机坐标与世界坐标的各个轴的朝向也是不同的,因此需要进一步通过旋转来对齐坐标轴的朝向,实现旋转的方式是在平移对齐坐标原点之后的基础上进行旋转,即与相机外参中的旋转矩阵 R 做矩阵乘法,对应得到代码中的rays_d。

旋转以对齐坐标轴的朝向

另附:NeRF的代码中其实还存在另外一个坐标系统:Normalized device coordinates(ndc)坐标系,一般对于一些forward facing的场景(景深很大)会选择进一步把世界坐标转换为ndc坐标,因为ndc坐标系中会将光线的边界限制在0-1之间以减少在景深比较大的背景下产生的负面影响。但是需要注意ndc坐标系不能和spherify pose(球状多视图采样时)同时使用,这点nerf-pytorch中并没有设置两者的互斥关系,而nerf-pl则明确设置了。

输入的进一步预处理

介绍完了将像素坐标转换到世界坐标形成光线始发点与方向向量之后,接下来便是文章中使用的一些trick,关于如何进一步处理光线起点与光线方向形成真正的MLP的输入值。

首先由于体素渲染需要沿着光线进行积分,而积分在计算机中是以离散的乘积和进行计算的,那么这里就涉及到在光线上进行点的采样。NeRF在光线的点采样过程中的进行了一些设计。首先为了避免大量的点采样导致的计算量的激增,NeRF设计了coarse to fine的采样策略。在coarse采样阶段,采用了带有扰动的均匀采样方法。第一步在光线的边界之间进行深度空间的均匀采样:

z_steps = torch.linspace(0, 1, N_samples, device=rays.device)
z_vals = near * (1-z_steps) + far * z_steps

然后在规定了下界与上界的范围内将采样点进行扰动:

z_vals_mid = 0.5 * (z_vals[: ,:-1] + z_vals[: ,1:])
upper = torch.cat([z_vals_mid, z_vals[: ,-1:]], -1)
lower = torch.cat([z_vals[: ,:1], z_vals_mid], -1)
perturb_rand = perturb * torch.rand(z_vals.shape, device=rays.device)
z_vals = lower + (upper - lower) * perturb_rand

最终coarse采样阶段在每条光线上采样了64个样本点。然后基于coarse采样得到的结果进一步指导fine的点采样,即在对最终颜色贡献更大(权重更大)的点附近进行更加密集的点采样。

然后是类似Transformer中的位置编码,将低维的坐标点与方向映射到高维空间以提升网络捕捉高频信息的能力,以nerf-pl中的代码nerf.py为例,embedding函数将3维的位置编码映射为63维,将3维的方向编码映射为27维。

处理好的样本点通过embedding函数进行低维到高维的映射之后得到的结果才会最终作为MLP的输入,MLP最终预测每个样本点的颜色值与不透明度。具体的网络结构图如下,NeRF为了建模view-specific的像素值,即不同的视角下看同一个点的颜色是有区别的,在网络的倒数第二层进一步把表示光线方向的高维编码输入以预测最终的像素值,而为了增强空间位置的condition,在网络的第四层又将表示位置的高维编码再一次输入到了网络中。

Nerf中MLP结构图

NeRF的训练

训练NeRF的输入数据是:从不同位置拍摄同一场景的图片,拍摄这些图片的相机位姿、相机内参,以及场景的范围。若图像数据集缺少相机参数真值,作者便使用经典SfM重建解决方案COLMAP估计了需要的参数,当作真值使用。

在训练使用NeRF渲染新图片的过程中,

  • 先将这些位置输入MLP以产生volume density和RGB颜色值;
  • 取不同的位置,使用体积渲染技术将这些值合成为一张完整的图像;
  • 因为体积渲染函数是可微的,所以可以通过最小化上一步渲染合成的、真实图像之间的差来训练优化NeRF场景表示。

这样的一个NeRF训练完成后,就得到一个以多层感知机的权重表示的模型。一个模型只含有该场景的信息,不具有生成别的场景的图片的能力。

除此之外,NeRF还有两个优化的trick:

  • 位置编码(positional encoding),类似于傅里叶变换,将低维输入映射到高维空间,提升网络捕捉高频信息的能力;
  • 体积渲染的分层采样(hierarchical volume sampling),通过更高效的采样策略减小估算积分式的计算开销,加快训练速度。

从MLP的输出到2D图像—体素渲染

在得到MLP对于某条光线中采样点的颜色与不透明度的预测值之后,便可以通过体素渲染进行该光线对应的像素颜色值的计算。这里的代码可以参考nerf-pl中的inference函数,每一步代码都有比较详细的说明。在训练阶段就将沿着特定光线预测的像素值与对应像素点的像素真值做L2损失函数以更新网络;在测试阶段就计算相机视锥中所有光线得到所有像素的像素值以组成完整的2D图像。

最后附上一些讲解关于相机内外参解释以及坐标系变换的资料:www.cs.cmu.edu/~16385/s17/Slides/11.1_Camera_matrix.pdf

ndc坐标系说明:github.com/bmild/nerf/files/4451808/ndc_derivation.pdf

Nerf-pytorch:https://github.com/yenchenlin/nerf-pytorch​

Nerf-pl:https://github.com/kwea123/nerf_pl​

Emitted Color & Volume Density

事实上 volume rendering的方法百百种,论文中使用的也只是其中一种依靠 emitted color与 volume density的方法。在论文中所谓的 volume density(密度)可以解释为这条射线会停在这个 3D位置的机率,而 emitted color指的是由某个视角看出去这个 3D位置的颜色

依照这样的设定, volume density在设计上应该只与 3D location有关,而 emitted color则是与 location与 view direction有关。因此 NeRF网路 (MLP) 会先吃进 3D location,通过 8层 FC layer,输出 volume density与 volume density以及 256维的 latent feature。而后与 view direction concatenate,在通过 FC layer得到 emitted color。

Vanilla NeRF

NeRF 所要做的 task 是 Novel View Synthesis,一般翻译为新视角合成任务,定义是:在已知视角下对场景进行一系列的捕获 (包括拍摄到的图像,以及每张图像对应的内外参),合成新视角下的图像。传统方法使用 IBR (Image Based Rendering) 方法的较多,也有一些使用深度学习和 IBR 结合的方法,这些我们不过多介绍。

NeRF 想做这样一件事,不需要中间三维重建的过程,仅根据位姿内参和图像,直接合成新视角下的图像。为此 NeRF 引入了辐射场的概念,这在图形学中是非常重要的概念,在此我们给出渲染方程的定义:

那么辐射和颜色是什么关系呢?我们不希望把这个文章讲复杂,简单讲就是,光就是电磁辐射,或者说是振荡的电磁场,光又有波长和频率,二者乘积为光速,光的颜色是由频率决定的,大多数光是不可见的,人眼可见的光谱称为可见光谱,对应的频率就是我们认为的颜色:

Positional Encoding

其实在 2018 年 Bengio 等人就发现 deep networks 更倾向于学习低频的函数,而可以想象的是,实际场景的神经辐射场基本上都是高频的,为此作者提出了 Positional Encoding(注意这里的 Positional Encoding 和 Transformer 中的 Positional Encoding 很像,但是解决问题是不一样的):

这里 p,L 都是标量, L 是超参数,对原始的坐标以及视角方向的每一维度都做相同的操作,然后再输入到网络中,事实上在官方的代码实现中,输入的是 (γ(p),p) ,也就是说原始信息也保留了下来。下图是一个关于 Positional Encoding 以及视角方向相关的 ablation study:

关于 Positional Encoding 以及 SIREN 等工作我们会在之后专门选一个章节进行讲解。读者暂时仅需保留一个印象即可。

Hierarchical volume sampling

使用体渲染积分就会遇到以下几个问题,虽然可以离散的近似计算积分,但是面临的问题就是如何采样。采样点过多开销过大,采样点过少近似误差有太大。直观的一个想法是,最好尽可能的避免在空缺部分以及被遮挡了的部分进行过多的采样,因为这些部分对最好的颜色贡献是很少的,基于这一想法 NeRF 提出分层采样训练的方式,如下图所示:

使用两个网络同时进行训练 (后称 coarse 和 fine 网络), coarse 网络输入的点是通过对光线均匀采样得到的,根据 coarse 网络预测的体密度值,对光线的分布进行估计,然后根据估计出的分布进行第二次重要性采样,然后再把所有的采样点 (Nc+Nf) 一起输入到 fine 网络进行预测。关于 loss 函数我们同样作为一个开放性的内容,不在此多做讲解了。

后NeRF时代

GIRAFFE:composition方向的代表作

2021CVPR的最佳论文奖得主GIRAFFE是NeRF、GRAF工作的延申。

在NeRF之后,有人提出了GRAF(Generative Radiance Fields),关键点在于引入了GAN来实现Neural Radiance Fields(神经辐射场);并使用conditional GAN实现对渲染内容的可控性。

在GRAF之后,GIRAFFE实现了composition。在NeRF、GRAF中,一个Neural Radiance Fields表示一个场景,one model per scene。而在GIRAFFE中,一个Neural Radiance Fields只表示一个物体,one object per scene(背景也算一个物体)。这样做的妙处在于可以随意组合不同场景的物体,可以改变同一场景中不同物体间的相对位置,渲染生成更多训练数据中没有的全新图像。

GIRAFFE实现composition

如图所示,GIRAFFE可以平移、旋转场景中的物体,还可以在场景中增添原本没有的新物体。

另外,GIRAFFE还可以改变物体的形状和外观,因为网络中加入了形状编码、外观编码变量(shape codes zsi , appearance codes zai )。

其他最新相关工作

2021年CVPR还有许多相关的精彩工作发表。例如,提升网络的泛化性:

  • pixelNeRF:将每个像素的特征向量而非像素本身作为输入,允许网络在不同场景的多视图图像上进行训练,学习场景先验,然后测试时直接接收一个或几个视图为输入合成新视图。
  • IBRNet:学习一个适用于多种场景的通用视图插值函数,从而不用为每个新的场景都新学习一个模型才能渲染;且网络结构上用了另一个时髦的东西 Transformer。
  • MVSNeRF:训练一个具有泛化性能的先验网络,在推理的时候只用3张输入图片就重建一个新的场景。

针对动态场景的NeRF:

  • Nerfies:多使用了一个多层感知机来拟合形变的SE(3) field,从而建模帧间场景形变。
  • D-NeRF:多使用了一个多层感知机来拟合场景形变的displacement。
  • Neural Scene Flow Fields:多提出了一个scene flow fields来描述时序的场景形变。

其他创新点:

  • PhySG:用球状高斯函数模拟BRDF(高级着色的上古神器)和环境光照,针对更复杂的光照环境,能处理非朗伯表面的反射。
  • NeX:用MPI(Multi-Plane Image )代替NeRF的RGBσ作为网络的输出。

5 不止是NeRF:Neural Rendering

Neural Radiance Fields的外面是Neural Rendering;换句话说,NeRF(Neural Radiance Fields)是Neural Rendering方向的子集。

在针对这个更宽泛的概念的综述State of the Art on Neural Rendering中,Neural Rendering的主要研究方向被分为5类,NeRF在其中应属于第2类“Novel View Synthesis”(不过这篇综述早于NeRF发表,表中没有NeRF条目)。

Neural Rendering的5类主要研究方向

表中彩色字母缩写的含义:

在这篇综述中,Neural Rendering被定义为:

Deep image or video generation approaches that enable explicit or implicit control of scene properties such as illumination, camera parameters, pose, geometry, appearance, and semantic structure.

Neural Rendering包含所有使用神经网络生成可控(且photo-realistic)的新图片的方法。“可控”指人可以显式或隐式地控制生成新图片的属性,常见的属性包括:光照,相机内参,相机位姿(外参),几何关系,外观,语义分割结构。在这个大框架下,NeRF是一种比较受欢迎的可控相机位姿的Neural Rendering算法。但Neural Rendering这个方向不止于此。

在目前的Neural Rendering方向,最火的子方向就是“Novel View Synthesis”,这与NeRF的强势蹿红密不可分;第二火的子方向是“Semantic Photo Synthesis”,这主要归功于语义分割以及相关的GAN领域的成熟度。“Semantic Photo Synthesis”方向也是成果颇丰,例如2019年CVPR的Semantic Image Synthesis with Spatially-Adaptive Normalization,其效果图如下。

Semantic Image Synthesis

最后我们给出一些 NeRF 的 paper list 以及代码整理:

综述论文

可以说是官方综述,作者列表是目前在Neural Rendering领域最活跃的一群人。两篇分别是2021、2020年的SIGGRAPH、CVPR讲座用到的综述,很全面很有条理,值得每位从业者一读!

SIGGRAPH 2021 Course: Advances in Neural Rendering

CVPR 2020 Tutorial: State of the Art on Neural Rendering

范围限定为可微渲染方法的综述:

Differentiable Rendering: A Survey