KinectFusion官方文档翻译

来源:互联网 发布:开源需求管理 php 编辑:程序博客网 时间:2024/06/10 14:20
KinectFusion官方文档翻译


Kinect Fusion的官方文档页面:https://msdn.microsoft.com/en-us/library/dn188670.aspx
Kinect Fusion项目主页面(含论文和视频):https://www.microsoft.com/en-us/research/project/kinectfusion-project-page/

kinect for windows SDK v1.7中引入了Kinect Fusion功能,在v1.8中对该功能进行了改进和加强。



什么是Kinect Fusion?
      Kinect Fusion使用Kinect提供3D物体扫描和模型构造,使用者可以用Kinect实时的绘制场景,同时可以看到重建的场景并交互式的重建出一个精细的3D场景模型。Kinect Fusion可以以交互速率运行在支持的GPU上,也可以以非交互速率运行在多种硬件上,以非交互速率运行可能允许更大量的重建。
  
图1:从Kinect中取出的深度图有很多丢失的数据,通过在场景附近移动Kinect,在几秒内就产生一个逼真的平滑的对静态场景的3D重建,由此就产生一个点云或一个3D网格。

准备开始(很重要!)
  1. 确定你有兼容的硬件(见下面的技术说明部分)。
  2. 为你的GPU下载并安装最新的图形显示驱动程序。

技术说明
      Kinect Fusion能够使用c++ AMP技术与DirectX11兼容的GPU上处理数据,也可以在CPU上处理数据,在重建时通过设置重建处理器的类型来确定。CPU处理模式最适合离线处理,只有最新的与DirectX兼容的GPU能够实时且交互地重建。

基于GPU重建的最低硬件要求
      基于GPU重建的最低硬件要求是与DirectX11兼容的显卡,Kinect Fusion将不会在不满足这个要求的硬件上运行。
      对Kinect Fusion 1.8的最低显卡要求还没有明确的测试,Kinect Fusion 1.7已经在NVidia GeForce GTX560和AMD Radeon 6950上进行了测试,这些显卡或是同一产品线的更高级别的显卡被预计能以交互速度运行。

推荐硬件
      有3GHz或更高的多核处理器的台式机,拥有2GB或更多内存的独立显卡,Kinect Fusion已经在NVidia GeForce GTX680 和AMD Radeon HD 7850上进行了测试用于更高端场景。
      注意:也可以在配置有DirectX11 GPU的笔记本上使用Kinect Fusion,但是运行速度比同类型的台式机要慢很多。通常支持跟Kinect一样的每秒30帧的处理就能满足最健壮的相机姿势追踪。

Kinect Fusion是如何工作的?
      Kinect Fusion通过对从多个视角获取的深度数据进行融合,来重建一个单一的稠密光滑表面模型。当传感器移动时,相机的姿态(其位置和方向)被追踪。因为我们知道了每一帧的姿态和如何与其他帧相互关联,所以这些对物体或场景的多个视角采集的数据能后融合成单一的重建好的体元立方体。我们可以想象一下空间中的一个大的虚拟立方体,里面是真实世界的场景,并且当传感器移动时深度数据被不断地融入里面。

处理流程
      Kinect Fusion的处理流程从原始的深度数据到3D重建这个过程包括几个步骤:
      

  • 第一步是深度图的转换。从Kinect取原始的深度数据,并把它转换为以米为单位的浮点深度数据,接着进行一个可选择的转换把浮点深度数据转换为在相机坐标系中由3D点组成的定向点云。这些点的表面法线使用AlignPointClouds函数获得。
  • 第二步是计算全局的相机姿态(其位置和方向),在传感器移动时使用一个迭代的配准算法追踪每帧的姿态,所以系统总是知道当前相机相对于初始起点帧的姿态。 Kinect Fusion有两个配准算法,第一个是NuiFusionAlignPointClouds,它用来把从重建中计算得到的点云与新进来从Kinect相机深度数据中获取的点云进行配准,或者单独配准(比如对同一场景的两个不同视角的数据进行配准)。第二个是AlignDepthToReconstruction,在对重建立方体进行处理时会提供更精确的相机追踪结果,然而对于场景中移动的物体该算法可能不够健壮。如果对场景的追踪中断了,把相机与最后一个追踪的姿态进行配准则追踪就继续了。
  • 第三步是将已知姿态的传感器获取的深度数据融合进一个相机视野范围内空间的体积代表(立方体)。这个对深度数据的融合是逐帧且连续的,同时使用一个平滑算法去噪,也进行了场景中一些动态改变(比如删除或增加一些小物体)。当传感器从略有不同的视角观察表面时,在原始的Kinect图像中缺少的深度数据形成的缺口或空洞也会被填充(比如在物体周围移动传感器去填充物体的背后部分),并且当相机更接近表面时,表面被新的高分辨率的数据不断细化。
  • 重建体积可以来自于一个传感器姿态(通常是但不限制于是当前的Kinect传感器姿态)的光线投影,并且对于一个3D重建体积的渲染可见的图像,合成的点云是可以被遮蔽。

      可以被扫描的典型的体积大小达到大约8m^3,典型的真实世界体元重建可以达到大约每体元1-2mm。然而,不可能同时具有这两者,详见下面的重建体积部分。

追踪
      Kinect Fusion的追踪仅仅使用 Kinect传感器的深度数据流。追踪依赖于每帧中深度数据的有足够的变化,使得在帧间可以匹配看到的并且计算帧间的姿态差异。如果你把Kinect对着一个单个的平面墙或是一个大多为平面的场景,将不会有足够的深度数据变化成功地追踪。杂乱的场景下追踪做的比较好,所以如果你试图扫描一个场景,如果追踪有问题的话,试图散布地放一些物体。
      Kinect Fusion中实现了两个追踪算法,是AlignDepthFloatToReconstruction函数和AlignPointClouds函数,两者都可以用于相机姿势追踪。然而,如果你创建了一个重建体积,AlignDepthFloatToReconstruction函数将可能执行更加精确追踪。与此相反,AlignPointClouds函数可以被单独使用,不需要一个重建体积去配准两个点云(对于单独使用的更多信息详见interface comments)。注意在INuiFusionReconstruction的接口的内部高级别的ProcessFrame函数使用AlignDepthFloatToReconstruction函数。
      AlignPointClouds追踪算法可选择输出为相机追踪算法配准结果的ARGB可视图像,当前根据每像素算法的输出进行颜色编码。 它可用作额外的视觉算法比如对象分割的输入。值根据像素是否是一个用于追踪的有效像素(内点)或在多个测试中被舍弃的像素(外点)而变化。0xff000000表明一个有效的输入点(比如从0输入深度数据)或是在点云图像间没有对应出现的点。外点被丢弃是由于点云间法线角的大的差异被编码为0xff8000。内点的颜色明暗取决于该点的剩余能量,有更多饱和的颜色意味着点之间差异很大,有较少饱和颜色表示点之间差异很小或是在该像素处有较少的信息。在好的追踪中,大部分的像素将呈现白色,通常在一些对象周围有少量的红色和蓝色像素,如果在整个图像中看到有大脸的红色、蓝色或绿色,这表示追踪可能丢失了或是相机姿态漂移了,重置重建将也会在这重置追踪。
       AlignDepthFloatToReconstruction追踪算法可选择输出为相机追踪算法配准结果类型NUI_FUSION_IMAGE_TYPE_FLOAT的图像,这个图像描述每个深度像素与重建模型配准的程度,它将会被处理创造一个颜色渲染或可能被用作额外的视觉算法比如对象分割的输入。这些剩余的值被归一化到-1到1并且表示每个像素的配准代价/能量。更大的值(正或负)表示更大的差异,更低的值表示更小的差异或该像素有较少的信息。注意如果存在有效的深度数据但在深度像素后没有重建模型,将会返回表示完美对准的0值。相反的,没有有效的深度数据出现将会返回1值。  

追踪的限制
      Kinect Fusion根据场景中的深度变化执行其相机追踪,场景必须在视野范围(或是在模型)有足够的深度变化使得成功地追踪。维持稳定的追踪最好在平移和旋转中进行又小又慢的移动。丢弃的帧可能会影响追踪,因为一个丢弃的帧实际上会引起处理帧之间的两次的平移和旋转移动。当使用AlignDepthFloatToReconstruction,通常可以引导用户将相机与最后追踪的位置和方向重新配准并继续追踪。

重建体积
      重建体积是由空间中的小立方组成的,小立方通常被称为体元。你可以通过将NUI_FUSION_RECONSTRUCTION_PARAMETERS结构传递给NuiFusionCreateReconstruction函数来指定体积的大小。可以创建的体元的数目取决于给重建设备能够分配的内存量,并且通常可以在具有1.5GB或更大内存的设备上创建总共达到大约640x640x640 = 262144000个体元。这个体积的纵横比可以是任意的,然而,你应该把体积体元的尺寸与打算扫描的真实世界场景区域的形状进行匹配。
       voxelsPerMeter成员衡量真实世界的1m所表示的体元,所以如果有一个384x384x384的体积,如果把voxelsPerMeter成员设置为128vpm则它在真实世界表示一个3m的立方体(因为384(v)/128(v/m)=3m,其中每个体元是3m/384=7.8mm^3),或者如果把voxelsPerMeter成员设置为256vpm则它在真实世界表示一个1.5m的立方体(因为384/256=1.5m,其中每个体元是1.5m/384=3.9mm^3),通过结合xyz坐标轴中的体元和每米表示的体元将能使你指定具有不同大小和分辨率的体积,但是注意这有个折衷——就是固定你可以创建的体元的数目你就不能创建一个表示很大的世界的非常高分辨率的体积。 
      在GPU上,通常可以分配的最大连续内存块为1GB,这就把重建分辨率限制为大约640^3(262144000个体元)。相似地,尽管CPU通常比GPU有更多内存,堆内存的碎片可能阻止更大大小的连续内存块的分配。如果你需要很高分辨率以及表示很大真实世界的体积,多个体积或多个设备可能是一个合理的解决方案。
       注意:如果你在GPU上做交互式的重建,则内存要求适用于GPU上的视频内存。如果你在CPU上做离线的重建,则内存要求适用于机器的主内存。
   
Kinect Fusion的例子
      开始Kinect Fusion的最好方法是首对将示例进行试验然后查看他们的代码。目前有8个示例——3个c++原始实例( Kinect Fusion Basics-D2D, Kinect Fusion Color Basics-D2D, and Kinect Fusion Explorer-D2D)和5个c#处理过的实例(KinectFusionBasics-WPF, Kinect Fusion Color Basics-WPF, Kinect Fusion Explorer-WPF, Kinect Fusion Explorer Multi-Static Cameras-WPF, and Kinect Fusion Head Scanning-WPF)。基本实例(basic sample)展示了启动Kinect Fusion的最快方式和Kinect Fusion操作所需最少的代码,而explorer sample 显示了很多API参数作为样本中的控件并且允许对Fusion功能进行更多的探索。
 
基本示例:Kinect Fusion Basics-D2D,KinectFusionBasics-WPF    
      基本示例提供最小的UI,包括重建的灰度阴影可视化,Kinect近景模式切换和重置重建按钮。 所有其他参数,包括重建大小在代码中设置。 基本示例调用INuiFusionReconstruction接口中的ProcessFrame函数,该函数把相机跟踪(AlignDepthFloatToReconstruction)和数据融合步骤(IntergrateFrame)封装在一个函数中,使得更容易去调用和更高效的,这样做是由于所有的处理都发生在GPU上,没有上传或读出各个步骤,在单独调用时才会发生上传或读出。在这里如果相机追踪成功的话重建才更新。
      注意杂乱场景的扫描能使相机追踪最好,对大部分是平面的场景增加物体。为了提取静态场景中特定场景和物体的网格,可以使用第三方网格处理工具随后手动删除对象。


图3. Kinect Fusion扫描桌面的基本应用(左—D2D,右—WPF)
  1. 首先确定你的机器符合最小的规格(见上),然后启用应用,你就应该看到一个类似与图3的窗口。
  2. 把传感器对准场景比如桌面,然后启动应用。你就应该看到在Kinect Fusion示例图像中桌面外观的表示。目前在示例中的分辨率在构造函数中被硬编码为512x384x512体元,其中256vpm(它是2x1.5x2m的重建体元)。
  3. 如果传感器丢失了追踪按重置按钮(请参阅窗口底部状态栏的丢失信息)。

基本示例:Kinect Fusion Color Basics-D2D,Kinect Fusion Color Basics-WPF
      基本颜色示例展示了Kinect Fusion的API选择使用颜色的3D重建的基本使用。从概念上来说这个示例是与普通的示例相似的,但是它使用了并行的颜色重建API。在使用颜色API时有一个内在的权衡,因为在重建体积中颜色数据的存储根据在显卡中可以创建的最大体积大小会有一个相应的减少(大约一半)。此外,在一些显卡上使用这些API和融合彩色数据将会花费额外的运行时间,并将降低观测的帧速率。


                                    图4. Kinect Fusion的颜色基本示例(左—D2D,右—WPF)

高级示例:Kinect Fusion Explorer-D2D,Kinect Fusion Explorer-WPF
      Explorer的UI比Kinect Fusion的参数上提供更多的可配置性,并且能执行网格化创建一个3D模型。

图5. Kinect Fusion的explorer sample,使用640^3体元(其中512vpm,是一个1.25m^3重建体积大小)扫描了一个女头部模型(左—D2D,右—WPF)
  1. 首先确定你的机器符合最小的规格(见上),然后启用应用,你就应该看到一个类似与图5的窗口。
  2. 窗口中的图像是:在右上方是Kinect原始深度数据,右下方是相机追踪的结果(详见上面的相机追踪部分),左边的大图是一个从相机姿态得到的重建体积中的主要光线投影和阴影视图。
  3. 把传感器对准一个场景比如桌面,然后启动应用,你就应该看到在Kinect Fusion示例图像中桌面外观的表示。目前在示例中的分辨率在构造函数中被硬编码为512x384x512体元,其中256vpm(它是2x1.5x2m的重建体元)。
  4. 如果传感器丢失了追踪按重置按钮(请参阅窗口底部状态栏的丢失信息)。
                                               
    图6.  深度阙值滑块,重置按钮,创建网格按钮,和在Kinect Fusion Explorer-D2D的其他配置
  5. 通过移动图6底部的深度阙值滑动条改变深度阙值参数,注意这个将会控制如何缩减右上角的深度图。Kinect Fusion需要深度数据,所以你需要在重建体积的区域内有有效的深度值。滑块以最小0.35m(接近最小的Kinect感应距离)和8m(接近最大的Kinect感应距离)开始,并且可以用于诸如背景或前景的去除。
  6. 尝试使用额外的配置框,如“显示表面法线”,“近景模式”和“镜像深度”。注意镜像深度将重置重建,“暂停融合”将停止重建体积融合深度数据,并且这个功能是有用的如果你已经完全重建了场景,现在仅仅想追踪相机姿态而不是更新体积中的场景(不进行融合将运行更快)。

    图7.  在Kinect Fusion Explorer-D2D中的重建体积设置
  7. 在图7中的重建体积设置能使你改变重建体积中真实世界的尺寸和的形状。试着玩一下,看看x,y,z和vpm如何影响体积中的真实世界的尺寸和可视的分辨率。
  8. “Maximum Intergration weight”滑动控制重建体积的平均时间——这个量增加将让系统有更高分辨率的重建,但会花费更长的时间并且不会适应去改变,这个量减少将会在深度改变时体积反应更迅速(如对象移动),但整体上会有更多的噪音。
  9. 点击图6中的“create mesh”按钮,由Kinect Fusion Explorer示例输出的网格模型是3D打印你扫描的场景和物体的第一步。注意大多数的3D打印机需要闭合的水密的而且无孔洞的网格模型去打印。通常对于3D打印这步需要手动清除或删除无关的几何,然后对3D几何进行插入修复孔洞。一些受欢迎的3D设计和编辑,或CAD软件包可以自动的执行孔洞修复,当扫描一个高分辨率的或预定目标是3D打印机时,我们建议使用二值的STL网格文件输出,因为该文件的大小小于ASCII格式.obj。
      注意:STL是无单位的格式,并且不同的网格应用将位置解释为不同的单位,在我们的示例中,我们假设每个单位是1m。

高级示例:Kinect Fusion Explorer Multi-Static Cameras-WPF
      多个静态相机的示例展示了如何把多个静态Kinect相机整合到同一个重建体积中,为每一个相机提供用户定义的变换。提供了第三方视角和基本的WPF图形允许用户在设置和捕获中可视的探索一个重建场景。为了控制虚拟的相机,左击并拖动旋转,右键点击并拖动平移,并且使用鼠标滚轮进行缩放。图形以绿色显示重建范围,以黄色显示单独的相机视锥。重建体积的原点和WPF图形的原点显示为分别对应于xyz轴的红色,绿色和蓝色的坐标轴线。

高级示例:Kinect Fusion Head Scanning-WPF
      头扫描示例展示了如何利用Kinect Fusion和人脸追踪的结合去扫描脸和头的高分辨率的模型。

移动vs静态传感器
      从概念上来说,一个移动的传感器和静态场景(比如场景扫描),一个静止的传感器和移动物体(比如物体扫描),Kinect Fusion两者都支持,但一般来说,移动的传感器和静态场景是更加鲁棒的,因为这存在相机追踪的大量变化的数据。
      对于用静态的传感器扫描物体,要确定物体有足够的深度变化并且覆盖足够大的Kinect图像,不会过于靠近导致深度范围为0
(这样通常就限制了你可以重建的物体的最小尺寸)。尝试使用Kinect Fusion Explorer-D2D示例中的深度阙值,或者在你的代码里调用NuiFusionDepthToDepthFloatFrame使物体与环境进行隔离。通过将输入深度图像周围的像素深度设置为0可选择地遮蔽重建中对象周围的环境。

多个GPU,阙值和重建体积
      Kinect Fusion可以使用多个GPU,然而,每个必须有自己的重建体积,因为一个单独的重建体积仅可以存在于一个GPU, 建议你的应用程序是多线程的,并且每个线程在调用NuiFusionCreateReconstruction时指定一个设备索引。
      在同一个GPU上也可以存在多个体积——仅需要对INuiFusionReconstruction创建多个实例, 单个的体积也可以用在多个线程的环境中。然而,注意如果正在从另一个线程调用,这个体积相关的功能将会被阻塞。


提示
  • 当要改善有问题的追踪时,给场景增加不同深度的杂乱。
  • 当使用静态的传感器扫描物体时,遮蔽背景的像素仅关注于对象。
  • 不要太快的或颠簸的移动传感器。
  • 监控Kinect深度图像,不要太接近要扫描的物体和表面。
  • 因为我们只依赖于深度数据,照明不是个问题(它甚至可以在黑暗中工作)。
  • 某些物体可能不会出现在深度图像中,因为他们吸收或反射太多的红外光——尝试从不同角度扫描物体去重建(特别是垂直于表面去扫描)。
  • 如果限制可利用的处理能力,则优选执行更小的体元分辨率的体积会更快和更好的追踪,高分辨率的体积会更慢和较差的追踪。
  • 如果在某物移动时表面没有从体积中消失,确保传感器看到有效的深度——如果在图像中是0深度,它不知道它可以删除这些表面,因为这也可能某物非常接近传感器内部的最小感应距离使得视野被遮挡。










    



0 0
原创粉丝点击