三维重建是指获取真实物体的三维外观形貌,并建立可复用模型的一种技术。它是当下计算机视觉的一个研究热点,主要有三方面的用途:1)相比于二维图像,可以获取更全面的几何信息;2)在VR/AR中,建立真实和虚拟之间的纽带;3)辅助机器人更好的感知世界。传统的三维重建方法主要是SfM(Structure from Motion),通过一系列不同位置采集的图像,离线计算出三维模型。帝国理工和微软研究院在2011年提出的KinectFusion开启了用RGBD相机实时三维重建的序幕。本文主要参考KinectFusion的论文[1-2],解析它的算法流程。

  KinectFusion由四部分组成(图1):首先,处理采集到的原始深度图,获取点云voxel的坐标以及法向量坐标;接着,根据当前帧的点云和上一帧预测出的点云计算当前相机的位置姿态;然后,根据相机位置姿态更新TSDF值,融合点云;最后根据TSDF值估计出表面。

  KinectFusion用一群voxel来描述三维空间。它把固定大小的一个空间(比如\[3m\times3m\times3m\])均匀分割成一个个小方块(比如\[512\times512\times512\]),每个小方块就是一个voxel,存储TSDF值以及权重。具体算法如下文所示。

1. 原始数据的处理

  流程和公式如图2所示。先对原始深度图\[R_k\]进行滤波降噪,这里选择双边滤波,目的是保持清晰的边界。一般的滤波是在空间域做加权平均,像素越靠近中心点,权重越高。双边滤波是在空间域加权平均的基础上再对值域加权平均,即像素灰度值越靠近中心像素的灰度值,权重越高。在边界附近,灰度值差异很大,所以虽然边界两边的像素在空间域靠在一起,但是由于灰度值差别非常大,对于互相的权重很低,所以可以保持清晰的边界,如图3所示。

  拿到降噪后的深度图\[D_k\]之后,再根据相机内参\[K\],可以反投影出每个像素点的三维坐标,这就是Vertex map \[V_k\]。公式中\[u\]是像素坐标,\[\dot{u}\]是对应的齐次坐标。每个vertex的法向量可以很方便的通过相邻vertex用叉乘得到。然后对深度图降采样,行数、列数各减一半。降采样使用的是均值降采样,即深度图上四个相邻像素的深度值被平均成一个值。构建三层金字塔的目的是为了从粗到细地计算相机位置姿态,有加速计算的效果。

2. 相机位置姿态的估计

  相机的位置姿态是用ICP (Iterative Closest Point) 求解的。ICP是处理点云的常规手段,通过最小化两块点云的差别,迭代求解出拍摄两块点云的相机之间的相对位置。有不同的方式来描述点云的差别,最常用的是point-to-point和point-to-plane两种。KinectFusion选择的是point-to-plane的方式,要把点到点的距离向法向量投影,如图4所示。2001年的一篇论文[3]详细比较了point-to-point和point-to-plane的效果,结论是point-to-plane要比point-to-point收敛速度快很多,而且更鲁棒。图5列出了[3]中的Figure15和16,比较了在两种点云形貌的情况下不同ICP的收敛速度和残差。

  损失函数的公式中,\[T_{g,k}\]是第\[k\]帧图片时相机在世界坐标系下的位置姿态,这是优化求解的对象。\[\dot{V}_k(u)\]是第\[k\]帧深度图上像素\[u\]反投影出的vertex坐标,\[\hat{u}\]是这个vertex在第\[k-1\]帧图片的投影。为什么这里\[\hat{V}_{k-1}^{g}\](不知道为什么下标\[k-1\]上标\[g\]打不出来)有hat上标呢?因为这里的vertex并不是直接在第\[k-1\]帧深度图上,而是第\[k-1\]帧融合TSDF后的预测值。如果直接用第\[k-1\]帧的数据,那这就是frame-to-frame的方式,会带来累计误差。而实际采用的是frame-to-model的方式,误差小很多。为了加速计算,这里利用了三层金字塔,从粗到细计算,最大迭代次数分别是\[[4,5,10]\]。

3. TSDF的更新

  先介绍一个概念SDF(Signed Distance Function),SDF描述的是点到面的距离,在面上为0,在面的一边为正,另一边为负。TSDF(Truncated SDF)是只考虑面的邻域内的SDF值,邻域的最大值是max truncation的话,则实际距离会除以max truncation这个值,达到归一化的目的,所以TSDF的值在-1到+1之间,如图6所示。

  TSDF的具体算法也在图6中,利用GPU并行处理各个voxel。首先把每个voxel根据计算出的相机位置姿态投影到相机上,如果在相机的视椎内,则会有一个像素点和它对应,\[D_i(p)\]是这个像素点距离表面的实际测量值,\[t_i-v^g\]则是voxel到相机的距离,两者的差就是SDF值。然后用max truncation归一化得到当前TSDF值。接着,用加权平均的方式更新TSDF值。voxel越正对着相机(如图7所示),越靠近相机,权重越大,用公式表示就是:\[W(p)\propto cos(\theta)/R_k(u)\],\[u\]是\[p\]的像。但论文[1]中也提到把权重全部设为1,对TSDF做简单的平均,也可以取得很好的效果;而如图6算法第12行,设置max weight后,可以去除场景中动态物体的影响(这一点没有特别想明白)。

4. 表面的估计

  更新完TSDF值之后,就可以用TSDF来估计表面。这样估计出来的表面比直接用RGBD相机得到的深度图有更少的噪音,更少的孔洞(RGBD相机会有一些无效的数据,点云上表现出来的就是黑色的孔洞)。具体的表面估计方法叫Raycasting。这种方法模拟观测位置有一个相机,从每个像素按内参\[K\]投射出一条射线,射线穿过一个个voxel,在射线击中表面时,必然穿过TSDF值为一正一负的两个紧邻的voxel(因为射线和表面的交点的TSDF值为0),表面就夹在这两个voxel里面。然后可以利用线性插值,根据两个voxel的位置和TSDF值求出精确的交点位置。这些交点的集合就呈现出三维模型的表面。

参考文献:

[1] Newcombe R A, Izadi S, Hilliges O, et al. KinectFusion: Real-time dense surface mapping and tracking[C]//Mixed and augmented reality (ISMAR), 2011 10th IEEE international symposium on. IEEE, 2011: 127-136.

[2] Izadi S, Kim D, Hilliges O, et al. KinectFusion: real-time 3D reconstruction and interaction using a moving depth camera[C]//Proceedings of the 24th annual ACM symposium on User interface software and technology. ACM, 2011: 559-568.

[3] Rusinkiewicz S, Levoy M. Efficient variants of the ICP algorithm[C]//3-D Digital Imaging and Modeling, 2001. Proceedings. Third International Conference on. IEEE, 2001: 145-152.

KinectFusion解析的更多相关文章

  1. Kintinuous解析

    版权声明:本文为博主原创文章,未经博主允许不得转载. Kintinuous是Thomas Whelan在National University of Ireland Maynooth读博期间的工作,有 ...

  2. 转:SLAM算法解析:抓住视觉SLAM难点,了解技术发展大趋势

    SLAM(Simultaneous Localization and Mapping)是业界公认视觉领域空间定位技术的前沿方向,中文译名为“同步定位与地图构建”,它主要用于解决机器人在未知环境运动时的 ...

  3. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  4. .NET Core中的认证管理解析

    .NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...

  5. Html Agility Pack 解析Html

    Hello 好久不见 哈哈,今天给大家分享一个解析Html的类库 Html Agility Pack.这个适用于想获取某网页里面的部分内容.今天就拿我的Csdn的博客列表来举例. 打开页面  用Fir ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  8. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  9. Asp.Net WebApi核心对象解析(下篇)

    在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...

随机推荐

  1. Java中参数传递问题

    Java中参数传递可以分为值传递和引用传递,话不多说直接撸代码 1.传原始类型(int,String等)数据是值传递 package test_1; public class Test { publi ...

  2. 【python】type()、instance()

    >>> a=520 >>> type(a) <class 'int'> >>> a=' >>> type(a) &l ...

  3. HTTP服务及状态码

    第一章 HTTP 1.1 HTTP协议的概念 HTTP协议,全称HyperText Transfer Protocol,中文名为超文本传输协议,是互联网上常用的通信协议之一,它有很多的应用.但是流行的 ...

  4. java二维码生成代码

    QRCodeUtil.encode(text, "D:/004.jpg", "D:", true, "exp");// 这个方法的第一个参数 ...

  5. Oracle数据库部分迁至闪存存储方案

    Oracle数据库部分迁至闪存存储方案 1.实施需求 2.确认迁移表空间信息 3.确认redo信息 4.确认undo信息 5.表空间迁移到闪存 6.redo迁移到闪存 7.undo迁移到闪存 8.备库 ...

  6. BZOJ 4818 SDOI2017 序列计数

    刚出炉的省选题,还是山东的. 自古山东出数学和网络流,堪称思维的殿堂,比某地数据结构成风好多了. 废话不说上题解. 1.题面 求:n个数(顺序可更改),值域为[1,m],和为p的倍数,且这些数里面有质 ...

  7. bzoj 2337: [HNOI2011]XOR和路径

    Description Input Output Sample Input Sample Output HINT Source Day2 终于把这个史前遗留的坑给填了... 首先异或的话由位无关性,可 ...

  8. /sbin/nologin 和 /bin/false 的区别

    /bin/false是最严格的禁止login选项,一切服务都不能用,而/sbin/nologin只是不允许系统login,可以使用其他ftp等服务 如果想要用false在禁止login的同时允许ftp ...

  9. asp.net core 2.0+sqlsugar搭建个人网站系列(0)

    一些废话 马上就要过年了,回顾这一年最大的收获就是技术有了很大的提升,其他的方面没有什么改变,现在还是单身小屌丝一枚. 这一年来学习的主要重点就是asp.net core,中间也使用 core+EF做 ...

  10. 手撕vue-cli配置文件——config篇

    最近一直在研究webpack,突然想看看vue-cli中的webpack是如何配置,查阅了很多相关的文章,所以也想出几篇关于vue-cli配置的东西.正所谓"工欲善其事必先利其器" ...