版权声明:本文为博主原创文章,未经博主允许不得转载。

  Kintinuous是Thomas Whelan在National University of Ireland Maynooth读博期间的工作,有四篇相关的论文(RSS RGB-D Workshop 2012,ICRA 2013,IROS 2013,IJRR 2014)。合作作者Michael Kaess来自CMU,是iSAM的作者(Kintinuous的后端优化用到了iSAM)。Thomas Whelan的另一项主要贡献是ElasticFusion,这是他在帝国理工大学Andrew Davison的实验室做博士后期间的工作。Kintinuous和ElasticFusion的区别在于,Kintinuous侧重于大范围(轨迹可以达到几百米)的三维重建,而ElasticFusion侧重于小范围(房间大小)的三维重建。其次,Kintinuous不支持来回扫描同一片区域并做融合,会出现层层叠叠、重复建模的现象,而ElasticFusion解决了这个问题。

  Kintinuous基于KinectFusion做出了三点改进:1)KinectFusion只在固定大小的空间做三维重建,而Kintinuous则把TSDF随着相机运动做平移,从而实现大范围的三维重建;2)KinectFusion在求解相机位置姿态时只利用了点云信息(Depth),而Kintinuous综合使用了点云信息和photometric信息(RGB),更加鲁棒;3)Kintinuous用DBoW实现了回环检测,并根据回环的约束优化三维重建。

  下图展示了Kintinuous的算法流程,它借鉴了PTAM的双线程架构,前端包含四部分内容:1)求解相机的位置姿态;2)TSDF融合,这部分是和KinectFusion一样的;3)如果相机运动超过阈值$m_s$,则平移TSDF,扩大三维重建的范围;4)如果相机运动超过阈值$m_p$,则提取SURF描述子,用DBoW找回环。后端包含两部分内容:1)基于iSAM对pose graph进行优化;2)利用优化后的pose graph,对三维重建进行调整。

1. 相机位置姿态的估计

  求解相机位置姿态的cost funcion包含两部分内容:

$$E=E_{icp}+w_{rgbd}E_{rgbd}$$

其中$E_{icp}$对应用ICP处理点云,$E_{rgbd}$对应photometric error,$w_{rgbd}$经验性地被设置为0.1($E_{icp}$单位是米,$E_{rgbd}$是256阶的灰度值)。

$$E_{icp}=\sum_k||(v^k-exp(\hat{\xi})Tv_n^k)\cdot n^k||^2$$

其中$v_n^k$表示第$n$帧图片的第$k$个vertex,$v^k$和$n^k$是对应的model上的vertex和normal,$T$是当前估计的相机位置姿态,$\hat{\xi}$是被估计的微调$T$的量。这部分的处理和KinectFusion一模一样,也是point-to-plane error,对应点之间的关系也是用投影的方式得到的,也是用三层的corse-to-fine的计算策略。

$$E_{rgbd}=\sum_{p\in{\mathscr{L}}}||I_n(p)-I_{n-1}(\Pi_{n-1}(exp(\hat{\xi})TV_n(p)))||^2$$

其中$p$是像素点反投影得到的三维坐标的空间点,$\mathscr{L}$是$I_{n-1}$和$I_{n}$两帧图片之间跟踪到的点的集合,$V_n(p)$是把点$p$投影到第$n$帧图片,$\Pi$是从homogeneous坐标得到二维的图像坐标。为了计算$E_{rgbd}$,在预处理阶段会先从RGB图像得到灰度图,然后用Gaussian kernel降采样成三层金字塔(KinectFusion是均值降采样)

  整个求解相机位置姿态的公式和ElasticFusion几乎一模一样,唯一的区别是,Kintinuous中$E_{icp}$是frame-to-model,$E_{rgbd}$是frame-to-frame,而在ElasticFusion中二者都是frame-to-model。论文[1]中解释photometric error为什么要用frame-to-frame而不是frame-to-model:因为作者发现在室内环境开着自动曝光和自动白平衡效果更好,而一旦曝光和白平衡变化,frame-to-model就不现实了,只能考虑短时间内frame-to-frame的photometric consistency。但这段解释不是很有道理,因为ElasticFusion完全是针对室内环境却没有采用同样的策略。

2. 大范围的TSDF融合

  TSDF的概念和融合方式就不再赘述了,可以参考KinectFusion解析。Kintinuous也是把一个立方体空间分割成$512\times512\times512$个voxel,每个voxel存储TSDF值(float16)、权重(1 byte)、RGB($1\times3$ bytes),所以为了维持这么多的voxel需要768MB($512^3\times6$ bytes)的内存。这里可以看出用voxel描述三维空间的一个非常大的问题:耗内存。所以为了实现大范围的三维重建,没办法过分增加voxel的数量,只能跟着相机的运动平移固定数量的voxel,而一旦voxel移出某个空间,这个空间的三维重建就定型了,没办法继续做融合。这也是为什么Kintinuous不支持来回扫描同一片区域,会重复建模。如下图所示,(i)中的每个小立方体是一个voxel,小立方体组成的大立方体是Kintinuous在GPU上管理的固定数量的voxel,这部分GPU内存被称为“循环缓冲区”(cyclical buffer),当相机沿着黑色箭头运动超过阈值$m_s$的距离,红色部分的voxel移出;(ii)沿三个轴(蓝色箭头)raycast出表面;(iii)展示的是重建出的点云;(iv)蓝色部分是新纳入三维重建的空间,这部分voxel就是红色部分空出来的voxel。

  但说实在的,我个人觉得这样的处理方式不是非常好,因为KinectFusion这套基于voxel的描述方式的最大问题在于大量voxel都是没有用的,只有物体表面的区域才需要voxel描述,Kintinuous看起来实现了大范围的三维重建,但是治标不治本,voxel的使用依然非常低效。相比而言,voxel hashing[2]和基于surfel[3]的方法更优雅。另一方面,不支持来回扫描同一片区域实在是个很大的缺点,RGBD相机的优点在于小范围的精细重建,应该做到反复扫描同一区域有更多的观测效果更好。如果单纯为了几百米范围的大规模三维重建,SfM可能是更好的处理方式。

3. 重定位

  Kintinuous的重定位方式和ORB-SLAM相似,都是对图片提取描述子,然后用DBoW找回环。差别在于ORB-SLAM用的是ORB描述子,而Kintinuous用的是SURF描述子。如果对每一帧图片都提取描述子,非常耗时而且没有必要。对于当前帧a和最近执行回环检测的那一帧b,Kintinuous经验性地设计了一个评价相对运动大小的量:

$$m_{ab}=||r(R_a^{-1}R_b)||_2+||t_a-t_b||_2$$

其中$r(R)$把旋转矩阵转换为3*1的轴角,Kintinuous只有在$m_{ab}$超过阈值$m_p=0.3$时才会执行回环检测。

  回环检测具体分三步:

  1)在RGB图提取SURF描述子,存入内存,为之后的查询做准备;

  2)把深度图存入内存,为了降低内存使用,会对深度图做压缩;

  3)在DBoW库中查询匹配,如果找到匹配则执行回环优化。判断匹配的标准:

    • 一旦有了候选的两帧匹配图像,用FLANN的k近领域的方法找图像上的匹配SURF特征,经验表明,少于35个就算没匹配上。
    • 候选的两个匹配图像,把其中一帧的图像的SURF特征点反投影成三维坐标,然后投影到另一帧,重投影误差小于2像素算内点。至少25%的匹配点是内点,否则舍弃回环。
    • 前两步已经筛掉了好多错误的回环匹配。现在继续用ICP再筛一遍。为了加速计算,会对深度图降采样。从两帧深度图得到各自的点云,然后计算点云的差别。小于阈值0.01,则被认为是可以的。

4. Space Deformation

  TODO

  

参考文献:

[1] Whelan T, Kaess M, Johannsson H, et al. Real-time large-scale dense RGB-D SLAM with volumetric fusion[J]. The International Journal of Robotics Research, 2015, 34(4-5): 598-626.

[2] Nießner M, Zollhöfer M, Izadi S, et al. Real-time 3D reconstruction at scale using voxel hashing[J]. ACM Transactions on Graphics (ToG), 2013, 32(6): 169.

[3] Keller M, Lefloch D, Lambers M, et al. Real-time 3d reconstruction in dynamic scenes using point-based fusion[C]//3D Vision-3DV 2013, 2013 International Conference on. IEEE, 2013: 1-8.

Kintinuous解析的更多相关文章

  1. Kintinuous 相关论文 Volume Fusion 详解

    近几个月研读了不少RGBD-SLAM的相关论文,Whelan的Volume Fusion系列文章的效果确实不错,而且开源代码Kintinuous结构清晰,易于编译和运行,故把一些学习时自己的理解和经验 ...

  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. SEO初步学习之新站优化

    新站优化技巧:新站有两个月扶持期,在扶持期间仅做一件事,提交大量优质受众的原创,且内容为不间断,即每天定点定量发布文章,使得蜘蛛对网站形成爬行习惯,新站初期内容为王,优化为辅. 虽说优化为辅,却不可或 ...

  2. PAT Basic 1007 素数对猜想 (20) [数学问题-素数]

    题目 让我们定义 dn 为:dn = pn+1 – pn,其中 pi 是第i个素数.显然有 d1=1 且对于n>1有 dn 是偶数."素数对猜想"认为"存在⽆穷多对 ...

  3. MySQL笔记(一)

    MySQL是目前最流行的关系型数据库管理系统之一,它是由MySQL AB公司开发.发布并支持.MySQL是一个跨平台的开源关系型数据库管理系统,被广泛地应用在internet上的中小型网站开发中.相比 ...

  4. Python基础学习四

    Python基础学习四 1.内置函数 help()函数:用于查看内置函数的用途. help(abs) isinstance()函数:用于判断变量类型. isinstance(x,(int,float) ...

  5. 5 分钟全面掌握 Python 装饰器

    ♚ 作者:吉星高照, 网易游戏资深开发工程师,主要工作方向为网易游戏 CDN 自动化平台的设计和开发,脑洞比较奇特,喜欢在各种非主流的领域研究制作各种不走寻常路的东西. ! Python的装饰器是面试 ...

  6. 吴裕雄--天生自然TensorFlow高层封装:解决ValueError: Invalid backend. Missing required entry : placeholder

    找到对应的keras配置文件keras.json 将里面的内容修改为以下就可以了

  7. spark mllib lda 简单示例

    舆情系统每日热词用到了lda主题聚类 原先的版本是python项目,分词应用Jieba,LDA应用Gensim 项目工作良好 有以下几点问题 1 舆情产品基于elasticsearch大数据,es内应 ...

  8. rsync+inotify实现文件实时同步

    一.相关组件简介 1.rsync 与传统的cp.tar备份方式相比,rsync具有安全性高.备份迅速.支持增量备份等优点,通过rsync可以解决对实时性要求不高的数据备份需求,例如定期的备份文件服务器 ...

  9. Java--java中的基本数据类型以及对应的包装类

    基本数据类型 序号 数据类型 长度(位数) 默认值 1 byte(整数型) 8 0 2 short(整数型) 16 0 3 int(整数型) 32 0 4 long(整数型) 64 0 5 float ...

  10. JavaScript关键字之super()

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/super The super keyword ...