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


文章目录

      • 0 前言
      • 1 理论基础
        • 1.1 书籍推荐
        • 1.2 SfM概述
      • 2 动手实践
        • 2.1 增量式SfM复现总结
        • 2.2 部分复现结果
        • 2.3 遇到问题与解决
      • 3 后续学习
        • 3.1 前沿论文阅读笔记
        • 3.2 Colmap使用问题
        • 3.3 三维旋转
        • 3.4 场景对齐

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流程图:
SfM|猿创征文|SfM(Structure from Motion)学习之路
文章图片

[1] Schonberger J L , Frahm J M . Structure-from-Motion Revisited[C]// IEEE Conference on Computer Vision & Pattern Recognition. IEEE, 2016:4104-4113.
SfM|猿创征文|SfM(Structure from Motion)学习之路
文章图片

[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的。除了这篇对整体流程的介绍博文外,我还记录了如下内容:
  • 增量式sfm复现实践——成果展示、易错问题总结及体会
  • 增量式sfm寻找下一最 佳匹配、获取pnp对应点、新加入图像三角化的trick
  • 经典/深度SfM有关问题的整理
    ??
2.2 部分复现结果 ??完成复现算法的工作后,部分实验数据和结果如下:

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

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

??
2.3 遇到问题与解决 ??在复现的过程中,会遇到不少问题。比如,在windows下使用C++进行开发,很容易遇到一些环境上的问题:
  • vs中使用‘fopen’、‘scanf‘等报错C4996:unsafe的解决方法及加了_CRT_SECURE_NO_WARNINGS后仍然报错的注意事项
  • error LNK2001: 无法解析的外部符号 “__declspec(dllimport) public等的常见解决方案小结
  • VS编译报错 “C2116不同声明之间的函数参数列表不匹配、C2371重定义;不同的基类型、C2733无法重载具有外部 “C“ 链接的函数”解决方案
  • xmemory Line: 141报错,在std::vector容器里装Vector2d等Eigen类型的数据时出错的根本性解决方案
  • 报错VC\Tools\MSVC\14.27.29110\include\xmemory Line: 141 Expression: invalidargument解决方案
【SfM|猿创征文|SfM(Structure from Motion)学习之路】??又比如,在使用ceres库进行BA求解,和安装gdal进行坐标系变换的时候,遇到的问题:
  • ceres报错F1211 problem_impl.cc:482 Parameter block not found和FAILURE invalidvalue解决方案
  • vcpkg安装配置gdal进行坐标转换及ERROR 6: Unable to load PROJ.4 library (proj.dll)解决方法
??
3 后续学习
3.1 前沿论文阅读笔记 ??通过上面的理论学习和实践,我们的基础就已经打的差不多了。但是,上面所做的一切并不涉及任何创新,所以,如果要进一步的研究的话,就需要去关注一下相关前沿工作,寻找创新点了。我后来的主要工作是围绕使用深度学习做SfM来进行的,一些相关的论文我也有进行了翻译或者做了笔记:
  • 2021年CVPR论文Deep Two-View Structure-from-Motion Revisited阅读笔记
  • 2021年ICCV论文Deep Permutation Equivariant Structure from Motion论文阅读笔记
  • 2020年ECCV论文DeepSFM: Structure From Motion Via Deep Bundle Adjustment阅读笔记
  • 2019年ICLR论文BA-NET: DENSE BUNDLE ADJUSTMENT NETWORKS论文阅读笔记
  • DROID-SLAM: Deep Visual SLAM for Monocular, Stereo, and RGB-D Cameras论文阅读笔记
    ??
3.2 Colmap使用问题 ??Colmap可以算是SfM领域一个里程碑式的工作了,上面也有所提及。它在2016年的CVPR会议上被提出,并开源了代码,做成了一个应用:项目主页、github链接。虽然已经是六年前的工作了,但是现在很多的涉及到位姿恢复的论文都会使用它来完成SfM工作。Colmap使用起来很方便,我也经常使用,但在使用过程中也遇到了一些问题,我将其记录了下来:
  • 【colmap数据格式转换】关于colmap稀疏重建结果的数据格式和数据库内容的一些笔记
  • 【踩坑记录】colmap中的相机位姿的坐标系定义及其可视化结果的隐含转换
    ??
3.3 三维旋转 SfM|猿创征文|SfM(Structure from Motion)学习之路
文章图片

??在三维领域,旋转始终是我们绕不开的话题。针对旋转矩阵,我也写了一些博客进行记录:
  • 四种三维空间旋转表示方法“轴角、旋转矩阵、欧拉角、四元数”之间的相互转换总结
  • 深入理解三维旋转矩阵——R的行和列分别有什么含义
    ??
3.4 场景对齐 ??我们还需要明确一个问题,通常来说,SfM是一个尺度未定的算法,也就是说,它恢复出来的场景和真实场景的尺寸并不是一样的,它们之间会相差一个相似变换(旋转、平移、缩放)。如果在深度学习的训练过程中,我们已知相机真值,那么,可以通过对齐恢复出来的相机与真值,来统一坐标系:
  • 使用普鲁克分析对两组相机/三维点(已知对应关系)进行相似变换对齐的方法及python代码
  • 两组相机(或三维点)对齐方法介绍及实现代码(求解相似变换,包含旋转R、平移t、尺度s)

    推荐阅读