Boundle Adjustment学习

本文分享了作者一年间学习光束平差的心路历程,从最初的基础薄弱到逐渐掌握,重点介绍了数学基础的重要性,特别是在理解最小二乘法、摄影测量学及结构从运动(SFM)中的应用。通过对比《数值分析》、《测量平差基础》等书籍,结合CeresSolver和SBA库的实践,解析了光束平差在图像拼接、相机校正中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

光束平差的学习断断续续有一年时间了,真正正儿八经的学习加起来大概有3个多月,从最初的迷迷茫茫开始有了感觉,记录一下;

一、学习历程

       实际上最开始了解光书法平差是调研SFM时大概看一眼介绍,绝对的懵逼状态,后来看各种论文、看PPT、看博客、看武大教材《测量平差基础》《摄影测量学》,然后,头很大,现在想想是因为很多相关基础完全不扎实,相机模型 、极线几何、最小二乘估计最优解的数学原理、前方交会、后方交会全都是模模糊糊有点概念上的印象,后来走了一个大大的弯路,发现SBA库专门解决光束平差问题,还是个开源库,欣喜若扛的开始下载源码、编译、配置环境、差文档、搜博客,居然完全没有中文相关的博客之类的介绍,于是开始自我怀疑;后来决心已定要搞定这个问题,于是从数学开始入手,因为看平差基础和很多PPT的时候发现,大家都用什么法方程,我居然一脸懵逼,还有迭代、残差,完全蒙蔽了,于是发现一本书《数值分析》,唉呀妈呀,研究生不好好学习的这门课,真的太棒了,花了一个月啃书,稍微打了点数学基础,之后了解过一点VSLAM等相关内容,发现光束平差真是个好东西,于是又开始补《多视几何》看了几章,看不下去了,又开始看《数值分析》同时发现这个博客,详细介绍了SFM的具体细节,讲的很明白,很好,之前貌似也见过但是看不进去,也许是当时的数学基础和多视几何基础太差了,于是这次一下就看明白了,爽得很,从这开始梳理清楚了连续图像之间是如何联系起来的,同时发现大家都用Google的开源库做平差,唉呀妈呀,从编译到教程再到各种大神博客的中文介绍,爽死了,于是下载Ceres Solver源码、编译、测试Demo,最终开始详细研究这位大神的笔记,收获颇丰。

二、一些想了很久也没想明白的问题

2.1关于最小二乘

       最小二乘的解释是很简单的,但是实际使用时面临很多问题,如何建模、如何求解、如何精度分析;实际上我就是抱着对最小二乘的迷惑,开始啃《数值分析》的,一路看过来,从不动点迭代、牛顿法学的爽死了,但是还是停留在书本里,昨天突然看到后方交会的PPT,对于后方交会求解时的公式、残差的使用,轰的一下想到了牛顿法,于是查书,终于发现了所谓的“法方程”的由来,同时明白了SLAM中PNP问题和摄影测量中的后方交会是一回事,至此收获了第一块内容,完全从心理上接受了法方程的使用、理解了所谓的残差,至此解决了一个由来已久的大疙瘩。同时发现,数学基础实在是太重要,没有数学基础想要做好机器视觉是不可能的,接下来还要继续学习。

2.2 SFM的学习

       SFM听说是很难得东西,所以一直没敢轻易去放开手脚的去学习;所以一直处于一知半解的状态,很不爽,尤其SLAM等火热的技术都与SFM相通,自从了解了最小二乘的很多内容以及摄影测量中的后方交会,对于SFM中涉及的内容不再感到陌生,很自然的就开始了比较深入的了解,这篇博客介绍的费城详细,让人一下了解了SFM的整个流程,并且生动形象的介绍了很多关键概念:内参矩阵、外参矩阵等等,同时最让人感到舒服的是几乎没有自己需要实现的代码,OpenCV3都有相应的功能,遗憾的是分享的代码需要50个币。

2.3 图像拼接中如何应用平差

      通过对SFM的理解学习,发现SFM主要目标是恢复空间结构,例如上面的博客中以第一张相片为基准开始后续的结构恢复,可是在图像拼接中,如何让整体的结构恢复到世界坐标中呢?想了一天,想明白了,不知道对不对,但是感觉应该是对的:就把第一张照片的POS和GPS当做是已经求解的外参矩阵,同时利用双目进行结构恢复,得到初始的一系列的3D点,这时这些点的坐标就是在WGS84坐标系下了,而且还带有尺度信息(两照片之间的GPS得到尺度信息),当然这个尺度信息是不准确的,但是至少得到了世界坐标系下的初始值,同时发现,这个初始值可以在任意两个相邻的图像间得到,而且安照Pix4D的经验,应该还可以同时获取很多这种初始值,这样一来每张图像的GPS和POS就可以直接当做SFM中计算出来的位姿,并且在平差时当做初始值进行平差,这是非常可靠的,这样一来整个过程就差如何图像配准并整理特定数据格式的参数文件了。

2.4 Ceres Solver中如何设置相机内参相同?

直接上代码吧:

ceres::CostFunction* cost_function =
        SnavelyReprojectionError::Create(observations[2 * i + 0],
                                         observations[2 * i + 1]);
    problem.AddResidualBlock(cost_function,
                             NULL /* squared loss */,//loss_function可以是别的,例如:HuberLoss可以得到更稳定的解
                             bal_problem.mutable_camera_for_observation(i),
                             bal_problem.mutable_point_for_observation(i));//注意这里:AddResidualBlock有好多种重构,这里把相机参数和点参数分开了,优快云中的SFM例子把相机参数又分为内参和外参,对于同一相机的情况,内参是相同的,单独出来更合理

三、基于OpenCV3.0+Ceres的SFM
       参考2.2中的博客,将SFM的整个流程实现,但是利用已有的无人机影像数据进行测试,模拟pix4D软件时,发现一个比较重要的问题:相机坐标系定义不同!本以为挺简单的问题,实际进行坐标系转换时还是比较麻烦的,中间测试了很多次,得到了正确的转换方法:图像拼接不用进行pnp,直接使用IMU+pos数据作为初始值,如果照片只有pos没有IMU就需要pnp求解位姿,以第一张图像为基准,再利用照片pos和pnp得到的照片相对位姿求解最优化的第一样影像的真实位姿,这就是为啥pix4D可以不用IMU数据就能得到世界坐标系下的拼接图像。

先看一下OpenCV中定义的相机模型

再看一下摄影测量学中的相机模型

通过代码调试,终于理清了各个环节的原理,总结一个流程示意图分享给大家:

最后j记录一些测试结果:

再提一点,相机畸变参数对于最终的BA结果影像很大,看下面:

BA虽然有现成的ceres库可用,但是如何代码实现LM还是很有意思,接下来继续啃

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值