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

article/2025/10/15 21:23:38

文章目录

      • 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流程图:

在这里插入图片描述
[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的。除了这篇对整体流程的介绍博文外,我还记录了如下内容:

  • 增量式sfm复现实践——成果展示、易错问题总结及体会
  • 增量式sfm寻找下一最 佳匹配、获取pnp对应点、新加入图像三角化的trick
  • 经典/深度SfM有关问题的整理
      

2.2 部分复现结果

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

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

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解决方案

  又比如,在使用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 三维旋转

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

  • 四种三维空间旋转表示方法“轴角、旋转矩阵、欧拉角、四元数”之间的相互转换总结
  • 深入理解三维旋转矩阵——R的行和列分别有什么含义
      

3.4 场景对齐

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

  • 使用普鲁克分析对两组相机/三维点(已知对应关系)进行相似变换对齐的方法及python代码
  • 两组相机(或三维点)对齐方法介绍及实现代码(求解相似变换,包含旋转R、平移t、尺度s)

http://chatgpt.dhexx.cn/article/gwjU2s7W.shtml

相关文章

SFM综述

Structure from Motion(SfM)是一个估计相机参数及三维点位置的问题。SfM方法可以分为增量式(incremental/sequential),全局式(global),混合式(hybrid),层次式&#xff08…

计算机视觉之三维重建-SFM系统

SFM系统 1.PnP问题2. RANSAC拟合3.本质矩阵与单应矩阵4.sift特征提取*2视图欧式结构恢复求解流程*openMVG系统Tracks联通图计算流程 北邮三维重建课笔记 1.PnP问题 PnP问题:就是利用其中两个相机算出三维点坐标,再利用三维点坐标和第三个相机的像平面坐标…

java中浮点数表示方式

java虚拟机中的浮点数分为float和double两种,分别为32位和64位.它参考了IEEE 754的规范对浮点数进行处理。下面以float为例 ,分析一下float数的表示方法. float的32位分成三个部分来表示一个浮点数: 浮点数的取值计算公式为: 解析: 1) 当…

一文读懂 IEEE754 浮点数的表示方法

FBI WARNING:鄙人首个开源电子书 《Go 编码建议》已经上线啦,欢迎各位大佬斧正指导,协同共建。 文章目录 1.浮点数的存储格式2.移码3.浮点数的规格化3.1 单精度浮点数真值3.2 双精度浮点数真值 4.浮点数的具体表示4.1 十进制到机器码4.2 机器…

浮点数表示(IEEE 754)

引入 N S r j N Sr^j NSrj N:浮点数S:尾数r:基数j:阶码 举个例子: 123.456 1.23456 1 0 2 123.456 1.2345610^{2} 123.4561.23456102 其中123.456是浮点数,1.23456是尾数,10是基数(10进…

c++ 浮点数表示

1.为何称为浮点数 对于一个浮点数来说,其通常可以科学计数法来表示,而对于一个浮点数来说,由于次方可变,故小数点可以左右移动。 eg:-36.5 ,及可以表示为:,也可以表示为&#xff0…

Java中浮点数的表示方法

Java中浮点数的表示方法 Java中浮点数的表示方法 1.计算机中的表示方法2.具体分析表示方法 小结 3.移位存储 小结 1.计算机中的表示方法 对于float来说,4个字节,32位,0-22位表示尾数,23-30(8位)表示指数,31位表示符…

浮点数的表示

科学计数法 浮点数的表示 阶码E反映表示范围及小数点的实际位置 位数M的数值部分的位数n反映浮点数的精度 浮点数尾数的规格化 左移三位 0.110;1.0100000 表示范围 浮点数标准 IEEE 754 移码 阶码真值移码-偏移量

dsp处理浮点数_DSP中浮点数的表示方法

DSP中浮点数的表示方法 tongxin | 2009-03-20 15:16:17 阅读:2484 发布文章 先介绍一下IEEE754中浮点数的定义(这里只介绍单精度浮点数): %A %A 单精度浮点数由4字节(32位)组成,且分成3段:数符s(0表示正数,1表示负数…

C语言浮点数的各种表示方法

2022.8.7更新 学习js的过程中发现了0.10.2更深一层的运算过程,感兴趣的可以看看这个博主写的帖子。 JavaScript 浮点数之迷:0.1 0.2 为什么不等于 0.3? ​​​​​​​ 前提: 由于存在精度限制,浮点数只是⼀个近似值&…

浮点数的表示方法是什么?

是已知的C/C编译器都是按照IEEE(国际电子电器工程师协会)制定的IEEE浮点数表示法来进行运算的。这种结构是一种科学表示法,用符号(或-)、指数和尾数来表示,底数被确定为2。所以在IEEE浮点数表示法里&#x…

浮点数表示总结

浮点数 早期的计算机使用定点数来表示实数,由于定点数的小数点位置固定,而计算机字长有限,定点数无法表示很大和很小的实数,因此而在计算机科学中有了对于实数近似值数值的表示法——浮点数。这种表示法类似于十进制中的科学计数…

计算机中浮点数表示

浮点数表示 浮点数在计算机中由符号位、指数和尾数组合而成。 通常,浮点数表示为如下形式: F为小数(尾数)字段值,E为指数字段值。 溢出(浮点的上溢):正的指数太大而超过了指数字段的表示范围。 下溢:负的指数太大而…

计算机组成原理浮点数表示

浮点数表示 浮点数的表示分为阶码和尾数; 比如3.026*1011;阶码是11;尾数是3.026; 对于阶码: 阶符为正,小数点向后移n位(n表示阶的大小); 阶符为负,小数点向前移n位(n表示阶的大小&a…

初步了解机器中浮点数表示方法

浮点数是小数点位置变化的数,能表示的范围比定点数大很多。 比如二进制数11.11可以表示为111.12-1或1.11121等,我们由此规律能得到二进制数更一般形式N2EF,E称为阶码,F称为尾数。这个数在机器里怎么存呢,是把正负符号…

32位浮点数表示方法

今天开始给大家介绍计算机组成原理课程,本文主要内容是32位浮点数表示方法。 一、32位浮点数构成 32位浮点数是计算机中常见的一种数据类型,该数占据32bit空间,可以表示较大范围内的整数和小数。32位浮点数由三部分组成,分别是符…

浮点的表示方法

浮点表示方法 一、浮点的表示方法一、单精度类型(float)二、双精度类型(double)三、IEEE 754标准 单精度名称本身的含义是“单字长精确的程度”。跟什么32位、64位有没有关系, 取决于系统支持的字长(word)是几个字节(…

浮点数的表示方法

把一个数的有效数字和数的范围在计算机的一个存储单元中分别予以表示。这种把数的范围和精度分别表示的方法,相当于数的小数点位置随比例因子的不同而在一定范围内可以自由浮动,所以称为浮点表示法。 在计算机中一个任意二进制数N可以写成: …

IOS磁力下载软件,老司机必备品

软件名为袋鼠下载,一款比较傲娇的APP目前仅支持iOS端,全程使用无广告无弹窗,关键支持任何资源的下载,直链、磁力、BT什么的通通不再话下,也不会针对性的进行限速,这样的免费产品在Android中都属不多见的精品…

这2个在线资源网千万别错过,老司机人手一份,一年省下好几千

早些时候,国内的电影资源网站大部分是搬运了国外的破解资源,并非自己 “ 原创 ” 出来的,这两天很多人都在想尽办法求《哪吒》熟肉资源,我们这边的电影院已经下播了,然后大家也知道,新出的电影在下播之后也…