KinectFusion: Real-time 3D Reconstruction and Interaction Using a Moving Depth Camera

KinectFusion仅用Kinect的深度信息来追踪相机的3D姿态,实时重建室内场景的3D模型。本文详细描述了KinectFusion的功能和新提出的基于GPU的流水线。这个核心GPU流水线的扩展表明了能够在不降低相机追踪和重建的精确度的情况下,直接在相机前进行物体分割和用户交互。

Kinect生成实时的实物场景的离散测量点深度图,这些测量值可以被投影到一系列离散3D点(点云)。Kinect的噪声会引起深度测量值波动,使深度图中包含没有读到的“空洞”。

为了达到实时重建高质量3D模型的效果,系统持续追踪相机的6D自由度,实时地把摄像得到的深度数据融合成一整个全局3D模型。随着相机移动,新拍摄到的物理场景融合到同一模型中,重建模型随着新的深度测量值加入而得到细节的完善,空洞被填补,模型也变得完善。重建的模型还可以运用Kinect的RGB相机进行纹理贴图。

法线贴图:在原物体的凹凸表面的每个点上均作法线,通过RGB颜色通道来标记法线的方向,若在特定位置上应用光源,可以让细节程度较低的表面生成高细节程度的精确光照方向和反射效果。

KinectFusion支持先重建出整个场景,再通过移动想要分离的物体,精确地将其分离出来。

 

GPU实现:

主流水线包括4个阶段:

1.Depth Map Conversion:把实时深度图从二维图像坐标转化到相机坐标空间的3D顶点(vertices)和法线。

2.Camera Tracking(ICP):在追踪阶段,用ICP算法的GPU实现,计算六维刚体变换,使每个当前有向点都与前一帧对应点紧密配准。所有相关变换都累积应用于一个单一变换,这个单一变换定义了Kinect的全局姿态。

3.Volumetric Integration:应用基于[5]的体积表面表示方法,给出相机的全局姿态,有向点就能转化到全局坐标系,单个的3D体素网格被更新。每个体素存储一个持续更新的由它到假定实物表面位置的平均距离。

4.Raycasting(3D Rendering):为了渲染给用户,整体被光线投射以提取隐式表面的视图。若给出相机的全局姿态,这个体光线投射视图就等同于一个合成深度图,这个合成深度图可用作下一次ICP迭代的全局一致的低噪参考帧。这使得我们能通过把当前实时深度图和模型的低噪光线投射视图进行配准来实现追踪。

以上每一步都是在GPU上使用CUDA并行执行的。

 

1.  Depth Map Conversion

在时刻i,每个CUDA线程并行地操作输入深度图Di(u)中一个单独的像素u=(x,y)。给定Kinect相机内部校准矩阵K后,每个GPU线程把一个深度测量值投影变换为相机坐标空间中的一个3D顶点:vi(u)=Di(u)K-1[u,1]。这样就并行地算出了一个顶点图Vi

每个顶点对应的法向量由使用每个GPU线程使用相邻投影点计算出来:ni(u)=(vi(x+1,y)-vi(x,y))×(vi(x,y+1)-vi(x,y))(标准化到单位长度ni/||ni||)。这样就并行地计算出了一个法线图Ni

在时刻i的6自由度(6DOF)相机姿态是一个刚体变换矩阵Ti=[Ri|ti],其中Ri是一个3*3的旋转矩阵,ti是一个3D平移向量。给定这个变换后,顶点和法线能分别转换到全局坐标系中:,。

 

2.  Camera Tracking

在KinectFusion中,ICP通过估算一个6DOF变换来追踪每个新深度帧的相机姿态,对当前帧中的有向点与之前的帧进行配准。这样得到一个相应的能够累加地应用到全局相机姿态Ti的6DOF变换。

ICP算法的第一步是:找到当前时刻i和前一时刻i-1的有向点的对应关系。在本文采用的系统中,我们使用投影数据关联(projectivedata association)来找到这些对应关系。这部分基于GPU的算法的伪代码为:

给定前一时刻的全局相机姿态Ti-1,每个GPU线程把一个独立点vi-1变换到相机坐标系空间中,并将其透视投影到图像坐标中。然后把这个2D点作为当前顶点(Vi)和法线图(Ni)中沿着射线(投影到同一图像坐标)查找对应点的查找索引。最后,每个GPU线程测试对应点的相容性以剔除异常值,首先把顶点和对应点都转换到全局坐标系中,然后测试它们之间的欧氏距离和角度是否在一个阈值之内。注意,Ti是由Ti-1来初始化的,并且由每次ICP迭代过程中计算出来的增量变换(incremental transform)来更新。

给定这些对应有向点的集合,每次ICP迭代的输出是一个将点到面误差度量最小化的单一变换矩阵T,定义为每个当前帧中的点与它在前一帧中对应点所在切平面的距离平方和:(1)

我们用一个线性近似来解决这个系统,假设在帧之间仅有一个增量变换。这个线性系统采用树规约方法(tree reduction)在GPU上并行运算与求和。这个6*6系统的解决方案为在CPU上使用乔利斯基分解(Cholesky decomposition)。

本文中基于GPU相机追踪实现的一个关键贡献是:ICP是在640*480的Kinect深度图提供的所有测量值上执行的。没有对点进行稀疏采样,也没有明确的特征提取(虽然ICP隐式地需要整合深度特征)。这种密集追踪方式只能用于本文中这种新的GPU实现,并且在KinectFusion里物体分割和用户交互中起到了重要作用。

 

3.  Volumetric Representation

通过使用ICP预测相机的全局姿态,所有深度测量值都能够从图像坐标系转换到一个一致的全局坐标空间。我们使用基于[5]的体表示(volumetric representation)方法来整合这些数据。预定义一个固定分辨率的三维体,将其映射到一个特定尺寸3D物理空间中。将这个三维体均匀地细分到3D体素网格中。使用一种符号距离函数(SDFs)的变体将全局3D顶点整合到体素中,SDFs值表示到实际表面的相对距离。当点在实际表面前面时,值为正;在实际表面后面时,值为负;表面交界处值定义为0。

实际上我们只存储实际表面附近的截断区域[5],即截断符号距离函数(TSDFs)。我们发现这种表示方法对于Kinect扫描数据有很多优势,尤其是和其他诸如网格的表示方法相比。它隐式地编码了距离数据的不确定性,高效地处理了多种测量值,随着新测量值的增加来填补空洞,能适应相机运动,而且隐式地存储了表面几何体。

3.1  Volumetric Integration

为了达到实时运算速度,我们使用一种新的体表示TSDFs的GPU实现。GPU给整个3D体素网格分配了线性内存。虽然有明显内存效率不足(一个包含32位体素的5123体积需要512MB的内存),但是运行速度是高效的。由于内存是连续排列的,所以并行线程的访问可以联合起来提高内存的吞吐量。

算法保证了能够合并访问体素网格,同时整合投影深度数据。算法实时更新体内的TSDF值(以每2ms更新5123体积的速度),并且允许连续表面估计从基于点的Kinect深度图中离散化到体素网格中。此外,这种方法比层次法更加易于实现,随着GPU可用内存的增加,本方法能扩展到为整个房间建模。

算法主要步骤的伪代码如图:

由于体积内通常包含大量的体素,所以不能给每个体素都创建一个GPU线程。为了保证合并内存访问,一个GPU线程被分派给每个体积前表面薄片的(x,y)点。然后GPU线程沿着z轴在每个薄片上移动,就并行地扫过整个体积。已知体积的分辨率,以及这个体积映射到的物理尺寸,每个离散的3D网格就能够被转化为全局坐标系的一个顶点。从相机中心(全局相机变换的平移向量)到这个顶点的度量距离是能够被计算出来的。这个3D顶点也能够被透视投影回图像坐标系以查找沿着射线的实际深度测量值。测量距离值和计算距离值的差值得出了一个新的体素SDF值(line 7)。将其标准化为一个TSDF(lines 9&11),并用一个简单的连续加权平均值(line 13)与之前存储的值做平均。新的权重和平均TSDF都存储在体素中。

3.2  Raycasting for Rendering andTracking

本文实现了基于GUP的光线跟踪(raycaster,是渲染的主要方法),用来渲染和追踪上一步中体(volume)内的隐式表面。伪代码如下:

每个GPU线程并行地沿着一条射线渲染输出图像中的一个像素。给定一个起点和射线的方向,每个GPU线程沿着射线穿过体素,通过观察零点交界(zero-crossing,沿着射线存储的TSDF值改变符号的位置)提取隐式表面的位置。最终表面交界点是在零点交界处左右两边分别由三线采样点用简单的线性插值法计算出来的。假设梯度和表面是正交的,则曲面法线可以通过在零点交界出求导直接算出。因此,每个找到射线/曲面交界点的GPU线程能够计算出一个插值顶点和法线,这些计算结果可以用作输出像素的光照计算的参数,用来渲染表面。

渲染流水线如图所示:

渲染流水线支持将传统的基于多边形的图形学组合到光线投射的视角中,以正确的遮挡处理技术混合(blending,常用的图像融合手段)虚拟和现实场景。在第一步(a)中,基于网格的场景以图形相机参数(与物理全局相机姿态Ti和内置校准矩阵K)来渲染。表面法线和未着色的数据不是渲染到帧缓存(framebuffer)和顶点缓存(vertex buffer)中,而是分别存储到屏幕外的顶点、法线和色彩图中(b),并且在光线投射时用作输入(c)。对于每个GPU线程,从关联网格顶点到相机中心的距离是在网格坐标系中计算的(Listing3,lines7&8)。在沿着射线前进时,这个距离作为一个额外的终止条件,支持在体积和网格表面几何间的精确遮挡检测。

环境光、漫反射、镜面反射的光效能够通过重建和虚拟几何图形来计算。更高级的着色计算可以通过沿着每条射线的第二次(或更多)反射来实现。阴影是在第一道光线打到一个体素或网格表面后(Listing3,lines13&19),通过从表面到光源的二次射线(使用网格坐标系)计算所得。如果光线在终止之前打到表面上,那么这个顶点就会又阴影。对于反光来说,一旦第一道光线达到表面上,一道新光线的方向就会基于表面法线和初试光线方向被计算出来。

本文光线追踪(raycaster)的贡献在于能够将重建模型的隐式表面可视化的能力,以正确的遮挡处理组合了多边形几何图形,并且提供高级的需要光线追踪操作的着色方法,这些全部是通过一个单一算法实时进行的。任何6DOF的图形相机变换都能够用来将物体光线投射,包括任意第三人称视角支持3D模型导航(navigation)。另一个关键贡献在于为ICP相机追踪生成了高质量的数据。当光线投射相机变换等于物理相机姿态时,提取的顶点和法线等同于深度和法线图(从和物理相机相同的视角看),但是与原始Kinect数据相比会少很多噪声、阴影和空洞。如[21]所示,通过直接追踪与帧到帧ICP追踪相反的光线投射模型,这样可以减少偏移问题和ICP错误。

 

4.  Simulating Real-World Physics

将真实和虚拟的几何结构进一步融合,GPU流水线可以扩展到支持虚拟物体和重建场景的真实物理碰撞拟真。基于[9][10],实现了GPU上的粒子仿真。场景的几何结构由一系列的静态例子仿真来表示。这些相同大小的球体保持静止,但是可以和其他动态模拟的粒子碰撞。虽然只是近似,但这个技术为目标体积内每个离散表面体素实时建模,并且即便是对很小的物体和任意形状的物体建模,都能达到良好的效果,比如书的边缘或者茶壶的把手。

静态粒子是在体积合成的时候创建的。随着体积被扫描过,在一个接近于零(定义表面交界处或零水平集)的自适应阈值内的TSDF值被提取出来。对每一个表面体素,都有一个静态粒子被实例化。每个粒子包含全局(度量)空间中的一个3D顶点,一个速度向量(对静态粒子来说是空),和一个ID。一个关键问题是碰撞检测。我们使用一个空间细分统一网格来区分相邻粒子。网格中的每个单元都有一个唯一的ID。通过将粒子的全局顶点转化到网格坐标系,每个动态或静态粒子被分配一个网格单元ID。我们系统中有两个列表:一个容纳静态粒子,另一个容纳动态粒子。在两个列表中,通过按照粒子当前的网格ID(使用基于GPU的基数排序)对粒子排序,将粒子被放入网格单元中。在每个模拟步骤中,为每个动态粒子创建一个GPU线程。每个线程通过检测(33)单元邻域(首先处理动态-动态的碰撞,然后处理动态-静态碰撞)来处理碰撞。离散元素法(DEM,Discrete Element Method)被用来计算一个当两个粒子碰撞时的速度向量。粒子的全局速度基于邻近碰撞、重力以及和包围体的碰撞而增加。然后每个粒子基于每个模拟步骤的累加速度重新定位。

本文基于GPU的流水线的主要贡献在于:在物理模拟取得突破进展的同时保持了交互速率,同时进行实时的相机追踪和重建。默认情况下,在光线投射过程中只有动态粒子被渲染,而且能够被重建的几何体正确地遮挡。

 

5.  Interacting in The Scene

目前描述的核心系统都基于场景保持合理静止的假设。显然,在一个互动场景中,用户想要在相机前自由运动并和场景交互。这样就产生了两个主要的难题。

第一,ICP追踪假定每一帧都会产生由于相机运动引起的单一刚性变换。用户在相机前的交互会导致独立于相机运动的场景运动,这种情况打破了假定条件。因为我们的ICP追踪是密集的(即使用所有可用的点集),所以我们的系统在处理瞬时的场景运动时是有弹性的。例如在图5中,即使用户移动了物体,也有足够的背景点供ICP汇聚。但是,过大或视角过长的场景运动会造成追踪失败。

第二,在我们系统支持实时重建的同时,表面预测也会随着时间得到改进细化,这是利用一个连续的加权平均距离值实现的。通过调整权重,就能给新的TSDF值更高的优先级,从而支持更快的模型更新,但代价是会有额外的噪声被引入重建结果中。实际上,权重的选择要平衡重建结果的质量和基于场景变化的重建定时更新。然而,这并不支持连续运动场景。通常,用户在场景中自由移动会导致相关深度数据只能被部分集成到体积中(如图8)。因为相机追踪直接依赖于这个模型,如果这个模型和实时数据不一致,就会产生错误。

5.1  ICP Outliers for Segmentation

为了探索用户和重建场景之间的动态交互,我们为核心GPU流水线提供了一种新的扩展。如图:

这种技术利用了密集ICP追踪的一种独特性质。当所有深度测量值被使用时,投影数据关联中的异常值会形成一个强有力的初始预测,如果有足够的刚性背景点供ICP聚集,这个预测就会成为独立于相机运动的场景运动的一部分。我们的解决方案能够稳定健壮地将一个运动的前景物体从背景中分割出来,能够减少追踪错误,并且使用户能够直接在场景中进行交互。

这个流水线假设至少有一部分刚性场景使用核心重建流水线(标记为a)重建完成。在初始扫描后,一个包含定向点的运动物体进入场景,这些定向点与已经重建的表面有显著差别。这些错误的ICP投影数据管理被复制到一个异常值映射(标记为b)中。接下来,一个深度感知连接的组成分析在异常值映射上运行,来聚集大量的连接碎片(connected patches),并除去由相机噪声(标记为c)导致的较小的异常值。在侦测到前景场景运动的地方,为了核心“背景”重建(标记为d),大量连接碎片被掩盖到输入深度图。这阻止了相关前景深度测量值在核心流水线中被用于重建或追踪。大量异常值的碎片能够使用第二个体积块(标记为e)被另外重建——潜在地应用于一个有着不同重建设定的独立GPU。最后一步光线投射两个独立的体积块,并抢输出结果(标记为f)合并,使用图12中相同的方法。

总的来说,我们的技术在稳定追踪方面取得了不错的结果,而且提高了静态背景的重建质量,甚至当部分场景在相机前连续运动也能达到好的效果。此外,这个技术能够健壮地分割出前景物体,并独立于背景进行重建。

5.2  Detecting Touch on Arbitrary Surfaces

这个流水线可以通过观察前景和背景的交叉部分来进一步拓展到支持多点触摸输入。我们将背景体积的默认光线投射拓展到输出一个触摸图(touch map),伪代码如列表4所示:

每个GPU线程使用光线投射前景顶点图作为输入,再次沿着光线穿过背景体积。如果定位到一个零交叉点,相关的前景顶点(沿着相同光线)会被检测(line 6)。如果前景和背景在范围内,前景位置即为触摸图中的输出。触摸图的一个深度感知连接组成分析抑制了噪声,并且随时间追踪标记了指尖。

 

6.  Towards Modeling of DynamicScenes

目前已经可以从背景中稳定地区分出移动的前景,这引出了一个有趣的问题,如何才能最好地重建这种移动表面。关键的挑战在于怎样把前景数据整合到第二体积中,使得表面测量值之间的关联能够随着时间得到保证。作为一个初步的探索,我们在另一个ICP实例中已经试验了单独预测前景对象的姿态。这次同样是运行密集ICP,但是仅使用前景有向点(从实时深度图和光线透视的第二体积得到)。实际上,我们已经发现,即使前景中有微小的非刚性运动,密集ICP也能使其收敛。这提供了一个关于全局相机变换,预测前景物体姿态的粗糙方法。

使用这个预测的姿态,可以将深度测量值配准并融合到第二体积中。对前景的表面预测能够随着时间建立起来,并逐渐变得精细完整。因为前景表面可能会移动,我们给被整合进来的新测量值更高的权重。一个简单的扩展使用每个体素的权重,该权重基于TSDF(整合之前)的导数的动态平均值不断调整。这使我们能够调整单个表面体素的权重,当变化率高的时候(例如手指或手)给予新测量值更高的权重,如果TSDF值稳定(例如前臂)就给予更低的权重。图16和图15显示了基于前景ICP追踪和每体素的自适应加权的初步结果。可以看出,结果与原Kinect数据相比,大幅度降低了噪声,用户的手臂、手和手指都很清晰,这个前景重建发生于侧相机追踪和背景重建的完善过程中。

对于我们的物理仿真,我们把整个前景重建表现为静态粒子,使移动的用户与动态粒子的碰撞被一帧一帧地建模(图9).这个重建移动前景的方法也能够用于纯粹地追踪用户手持的刚性物体的姿态,使追踪不依赖与相机运动,并且不需要标记和物体的先验知识。


阅读更多

没有更多推荐了,返回首页