ORB 优化(5)

ORB-SLAM作为单目SLAM,其精度很大程度上决定于帧与帧之间的位姿优化的是否准确。因此优化(optimization)在ORB-SLAM里面扮演了很重要的角色。这一小节探讨一下ORB-SLAM里用到的优化。

ORB-SLAM选用g2o作为图优化的方法,关于g2o可以参考http://www.cnblogs.com/gaoxiang12/p/5304272.html

一、为什么要优化

因为摄像机标定(camera calibration)和追踪(tracking)的精度不够。摄像机标定的误差会体现在重建中(比如三角法重建时),而追踪的误差则会体现在不同关键帧之间的位姿中,和重建中(单目)。误差的不断累积会导致后面帧的位姿离实际位姿越来越远,最终会限制系统整体的精度。

1.1 摄像机标定

单目SLAM文献中一般假设摄像机标定的结果是准确的,并不考虑这个因素带来的误差(大概因为很多时候跑标准的数据集,认为摄像机标定的误差是相似的)。然而对于一个产品,不同类型的传感器对应的标定误差并不相同,甚至有可能差异很大。因此,如果要评估整个系统的精度,这方面的误差必须要考虑进去。

1.2 追踪

无论在单目、双目还是RGBD中,追踪得到的位姿都是有误差的。单目SLAM中,如果两帧之间有足够的对应点,那么既可以直接得到两帧之间的位姿(像初始化中那样),也可以通过求解一个优化问题得到(如solvePnP)。由于单目中尺度的不确定性,还会引入尺度的误差。由于tracking得到的总是相对位姿,前面某一帧的误差会一直传递到后面去,导致tracking到最后位姿误差有可能非常大。为了提高tracking的精度,可以1. 在局部和全局优化位姿;2. 利用闭环检测(loop closure)来优化位姿。

二、如何优化

2.1 优化的目标函数在SLAM问题中,常见的几种约束条件为: 1. 三维点到二维特征的映射关系(通过投影矩阵);2. 位姿和位姿之间的变换关系(通过三维刚体变换);3. 二维特征到二维特征的匹配关系(通过F矩阵);5. 其它关系(比如单目中有相似变换关系)。如果我们能够知道其中的某些关系是准确的,那么可以在g2o中定义这样的关系及其对应的残差,通过不断迭代优化位姿来逐步减小残差和,从而达到优化位姿的目标。

2.2 局部优化

当新的关键帧加入到convisibility graph时,作者在关键帧附近进行一次局部优化,如下图所示。Pos3是新加入的关键帧,其初始估计位姿已经得到。此时,Pos2是和Pos3相连的关键帧,X2是Pos3看到的三维点,X1是Pos2看到的三维点,这些都属于局部信息,共同参与Bundle Adjustment。同时,Pos1也可以看到X1,但它和Pos3没有直接的联系,属于Pos3关联的局部信息,参与Bundle Adjustment,但取值保持不变。Pos0和X0不参与Bundle Adjustment。

因此,参与优化的是下图中红色椭圆圈出的部分,其中红色代表取值会被优化,灰色代表取值保持不变。(u,v)是X在Pos下的二维投影点,即X在Pos下的测量(measurement)。优化的目标是让投影误差最小。

2.3 全局优化

在全局优化中,所有的关键帧(除了第一帧)和三维点都参与优化。

2.4 闭环处的Sim3位姿优化

当检测到闭环时,闭环连接的两个关键帧的位姿需要通过Sim3优化(以使得其尺度一致)。优化求解两帧之间的相似变换矩阵,使得二维对应点(feature)的投影误差最小。

如下图所示,Pos6和Pos2为一个可能的闭环。通过      

      之间的投影误差来优化    

2.5 Sim3上的位姿优化

单目SLAM一般都会发生尺度(scale)漂移,因此Sim3上的优化是必要的。相对于SE3,Sim3的自由度要多一个,而且优化的目标是矫正尺度因子,因此优化并没有加入更多的变量(如三维点)。

作者在检测到闭环时在Sim3上对所有的位姿进行一次优化。定义Sim3上的残差如下:

            

其中    

的初值是尺度为1的Pos i相对于世界坐标系的变换矩阵。     为Pos i和Pos j之间的(Sim3优化之前的)相对位姿矩阵,表示        

之间的测量(measurement)。此处相当于认为局部的相对位姿是准确的,而全局位姿有累计误差,是不准确的。

 三、小结

个人理解,单目SLAM中的优化需要更多技巧,要有明确的优化目标,要仔细权衡其中的参数选择、自由度、速度和稳定性。

<think>嗯,用户问的是ORB-SLAM中的BA优化实现和改进方法。首先,我需要回忆一下ORB-SLAM的基本结构。ORB-SLAM主要分为跟踪、局部建图和闭环检测三个线程,而BA优化主要在局部建图和闭环检测中使用。 BA(Bundle Adjustment)在ORB-SLAM中应该是在局部地图优化和全局优化时进行的。记得ORB-SLAM使用的是g2o库作为优化后端,所以需要确认这一点。用户可能想了解具体的实现细节,比如如何构建图优化模型,使用的节点和边是什么类型的。 在实现部分,应该分步骤说明:数据结构准备、图模型构建、优化策略、参数设置。比如,关键帧和地图点作为顶点,观测关系作为边。需要提到使用的鲁棒核函数,比如Huber,以及优化后的外点处理机制。 改进方法方面,ORB-SLAM3可能对BA有改进,比如加入IMU或视觉惯性BA。此外,可能提到使用其他优化库如Ceres,或者增量式BA、滑动窗口法来提升效率。还有边缘化策略和自适应参数调整,比如根据运动状态调整迭代次数。 用户提供的引用中,引用[1]提到了两阶段的全局-局部图优化,这可能和ORB-SLAM的全局BA与局部BA有关,可以引用这一点。引用[3]提到图形学中的算法,可能和BA中的优化算法或数值方法有关联,但不太确定是否需要引用。需要检查引用内容是否相关,再决定是否加入。 还要注意生成相关问题,可能涉及BA的作用、与其他SLAM的区别、实时性挑战、鲁棒性处理等。确保问题覆盖用户可能关心的其他方面。 需要验证提到的优化策略是否准确,比如ORB-SLAM是否真的使用Huber核函数,以及边缘化的具体应用。可能还需要确认ORB-SLAM3中的改进点,比如视觉惯性BA的具体实现方式。 最后,确保回答结构清晰,分点说明,并且引用正确。可能需要调整语言更口语化,但按照用户要求,使用中文回答,并符合格式要求。</think>### ORB-SLAM中的BA优化实现与改进方法 #### 一、ORB-SLAM的BA优化实现 1. **BA的作用与层级** - **局部BA**:优化当前关键帧及其共视关键帧,以及这些关键帧观测到的地图点,减少局部累积误差[^1]。 - **全局BA**:在闭环检测后优化所有关键帧和地图点,确保全局一致性。 - 数学形式可表示为最小化重投影误差: $$ \min_{\mathbf{T}_i, \mathbf{P}_j} \sum_{i,j} \rho \left( \|\pi(\mathbf{T}_i \mathbf{P}_j) - \mathbf{u}_{ij} \|^2 \right) $$ 其中$\mathbf{T}_i$为位姿,$\mathbf{P}_j$为3D点,$\rho$为Huber鲁棒核函数。 2. **实现步骤** - **数据结构准备**:提取当前激活的关键帧集合及其观测的地图点。 - **图模型构建**: - 关键帧位姿作为SE(3)节点 - 地图点坐标作为3D点节点 - 观测关系构建一元边(单目)或二元边(双目) - **优化策略**: - 使用g2o库的LM(Levenberg-Marquardt)优化器 - 固定非活跃关键帧的位姿 - 采用两级优化:先优化位姿再联合优化位姿与地图点 3. **代码级实现(简化逻辑)** ```cpp void Optimizer::LocalBundleAdjustment(KeyFrame* pKF, bool* pbStopFlag) { // 1. 获取局部关键帧集合 vector<KeyFrame*> vLocalKeyFrames = pKF->GetVectorCovisibleKeyFrames(); // 2. 构建优化器 g2o::SparseOptimizer optimizer; g2o::BlockSolver_6_3::LinearSolverType* linearSolver = new g2o::LinearSolverEigen<g2o::BlockSolver_6_3::PoseMatrixType>(); g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg( new g2o::BlockSolver_6_3(linearSolver)); // 3. 添加顶点与边 for(KeyFrame* pKFi : vLocalKeyFrames) { g2o::VertexSE3Expmap* vSE3 = new g2o::VertexSE3Expmap(); vSE3->setEstimate(Converter::toSE3Quat(pKFi->GetPose())); optimizer.addVertex(vSE3); // 添加地图点观测边 for(MapPoint* pMP : pKFi->GetMapPoints()) { g2o::EdgeSE3ProjectXYZ* e = new g2o::EdgeSE3ProjectXYZ(); e->setVertex(0, dynamic_cast<g2o::OptimizableGraph::Vertex*>(vSE3)); // ... 设置其他参数 optimizer.addEdge(e); } } // 4. 执行优化 optimizer.initializeOptimization(); optimizer.optimize(5); // 迭代5次 } ``` #### 二、改进方法 1. **算法层面的改进** - **视觉惯性BA**(ORB-SLAM3新增): $$ E = \sum \rho(\| \mathbf{r}_{IMU} \|_{\Sigma_{IMU}}^2 ) + \sum \rho(\| \mathbf{r}_{proj} \|_{\Sigma_{img}}^2 ) $$ 联合优化相机位姿、速度、IMU偏置和地图点[^1]。 - **滑动窗口BA**:限制优化关键帧数量,保持实时性。 - **边缘化策略**:使用Schur补消除旧关键帧的状态,保留其约束信息。 2. **工程优化** - **增量式BA**:仅优化受新观测影响的部分变量 - **多线程加速**:将雅可比矩阵计算与线性求解步骤并行化 - **自适应参数调整**:根据运动剧烈程度动态调整迭代次数 3. **鲁棒性增强** - **动态权重分配**:基于特征匹配质量调整信息矩阵权重 - **多假设BA**:维护多个优化假设,选择最一致的解 #### 三、典型改进案例 DiSCo-SLAM提出的两阶段优化框架[^1]: 1. **第一阶段**:分布式局部BA优化 - 各机器人独立优化局部地图 - 采用scan context进行快速数据关联 2. **第二阶段**:全局一致性优化 - 整合各局部优化结果 - 构建全局位姿图进行轻量级优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值