猿创征文|SfM(Structure from Motion)学习之路

0 前言

  一转眼,研究生生活已经过去两年了。开始接触SfM也是两年前的事了,至于缘由,谈不上为啥,一开始自己并没有明确喜欢的方向。现在回过头来看,我没有后悔学它,SfM可以称得上自己比较喜欢的一个技术类型了。不过SfM是一个已经有几十年研究历史的技术了,所以目前的话,想从传统流程上入手去进行改进的空间比较小也比较难。
  SfM全称Structure from Motion,译为运动恢复结构,是三维重建pipeline的一部分,又称稀疏重建,在摄影测量领域则称为空三(空中三角测量)。SfM的任务是,给定一系列具有一定重叠度的图像,去同时估计出拍摄每张图像时相机的位姿(位置t和姿态R)和被拍摄物体或场景的稀疏点云。
  

1 理论基础

1.1 书籍推荐

  初次接触SfM,我先看了两本书,一本是《视觉SLAM十四讲》,另一本是《计算机视觉中的多视图几何》。需要特别说明的一点是,SfM与SLAM(Simultaneous Localization and Mapping,即时定位与地图构建)在很多步骤上是类似的。区别在于,SfM不要求实时性,对重建场景的精度要求更高;而SLAM要求实时性,对相机定位要求也较高,但是对场景的稠密性要求比较低。所以,《视觉SLAM十四讲》作为一本SLAM入门必读书籍,也就当仁不让地成为了入门SfM的好书之一。这两本书我都读了有好几遍,其中《视觉SLAM十四讲》更通俗易懂,对于技术目的的理解很有帮助;而《计算机视觉中的多视图几何》则比较深奥,涉及的数学几何知识更多。由于我学习的是增量式SfM,很多步骤和SLAM都是一样的,所以《视觉SLAM十四讲》对我的帮助尤甚。
在这里插入图片描述
  

1.2 SfM概述

  上面提到了增量式SfM,这里就顺便简单介绍一下SfM的分类。传统的SfM可以分为全局式和增量式两大类,当然还有其他一些混合的方法,比如层次式。全局式(Global)SfM能够一次性得出所有的相机姿态和场景点结构。它通常先求得所有相机的位姿,然后再通过三角化获得场景点。其中相机位姿求解也分为两步:第一步是求解全局旋转,第二步是根据全局旋转求解全局平移向量。因为第二步的计算依赖于第一步的输出,因此第一步输出结果的准确性直接决定了第二步的结果的优劣,也就是说,全局旋转的求解是相机姿态估计的核心关键问题。全局式SfM只需要在最后进行一次BA(Bundle Adjustment),因此效率较高,但是其鲁棒性差,很容易受到outlier的影响而导致重建失败。增量式(Incremental)SfM则是一边三角化(triangulation)和pnp(perspective-n-points),一边进行局部BA。这类方法在每次添加图像后都要进行一次BA,效率较低,而且由于误差累积,容易出现漂移问题;但是增量式SfM的鲁棒性较高。著名的开源库Colmap(Colmap论文——《Structure-from-Motion Revisited》论文阅读笔记)就是通过增量式SfM的pipeline实现的。而OpenMVG(OpenMVG论文——《Global Fusion of Relative Motions for Robust, Accurate and Scalable Structure from Motion》论文阅读笔记)则同时实现了增量式和全局式两种pipeline。如下两图分别是增量式SfM和全局式SfM流程图:

在这里插入图片描述
[1] Schonberger J L , Frahm J M . Structure-from-Motion Revisited[C]// IEEE Conference on Computer Vision & Pattern Recognition. IEEE, 2016:4104-4113.

在这里插入图片描述
[2] Barath D , Mishkin D , Eichhardt I , et al. Efficient Initial Pose-graph Generation for Global SfM[C]// Computer Vision and Pattern Recognition. IEEE, 2021.

  

2 动手实践

  在看了一些相关的书籍和论文之后,就需要开始动手实践了。其实一开始光看书或者论文的话,你会发现很飘:书本内容虽然看了又看,但是就是记不住,看过就忘了。而通过实践,再从实践中去深入理解每一个步骤的细节,进行查漏补缺,这样才能真正学进去。我在Windows系统下,在visual studio中使用C++语言进行开发,自己动手实现了完整的增量式SfM。当然,其实SfM的参考资料并不很多,甚至于我们看的《视觉SLAM十四讲》也是关于SLAM的而不是SfM,所以在入门时候会比较困难。如果身边可以有熟悉这一技术的人带你就再好不过了。
  

2.1 增量式SfM复现总结

  增量式SfM的主要流程包括特征点提取与匹配、RANSAC误匹配剔除、初始化视图选择、三角化生成场景点、pnp估计下一视图位姿、BA(bundle adjustment)等。关于具体流程的介绍,我在复现之后,写了一篇总结的博文:增量式SfM详细流程介绍及实现方法。里面有对SfM的比较细致的介绍,对每一个步骤的描述,以及我是如何实现这个pipeline的。除了这篇对整体流程的介绍博文外,我还记录了如下内容:

2.2 部分复现结果

  完成复现算法的工作后,部分实验数据和结果如下:

在这里插入图片描述
在这里插入图片描述
  

2.3 遇到问题与解决

  在复现的过程中,会遇到不少问题。比如,在windows下使用C++进行开发,很容易遇到一些环境上的问题:

  又比如,在使用ceres库进行BA求解,和安装gdal进行坐标系变换的时候,遇到的问题:

  

3 后续学习

3.1 前沿论文阅读笔记

  通过上面的理论学习和实践,我们的基础就已经打的差不多了。但是,上面所做的一切并不涉及任何创新,所以,如果要进一步的研究的话,就需要去关注一下相关前沿工作,寻找创新点了。我后来的主要工作是围绕使用深度学习做SfM来进行的,一些相关的论文我也有进行了翻译或者做了笔记:

3.2 Colmap使用问题

  Colmap可以算是SfM领域一个里程碑式的工作了,上面也有所提及。它在2016年的CVPR会议上被提出,并开源了代码,做成了一个应用:项目主页github链接。虽然已经是六年前的工作了,但是现在很多的涉及到位姿恢复的论文都会使用它来完成SfM工作。Colmap使用起来很方便,我也经常使用,但在使用过程中也遇到了一些问题,我将其记录了下来:

3.3 三维旋转

在这里插入图片描述
  在三维领域,旋转始终是我们绕不开的话题。针对旋转矩阵,我也写了一些博客进行记录:

3.4 场景对齐

  我们还需要明确一个问题,通常来说,SfM是一个尺度未定的算法,也就是说,它恢复出来的场景和真实场景的尺寸并不是一样的,它们之间会相差一个相似变换(旋转、平移、缩放)。如果在深度学习的训练过程中,我们已知相机真值,那么,可以通过对齐恢复出来的相机与真值,来统一坐标系:

  • 20
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zeeq_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值