【SLAM】【后端优化】不同优化方法对比

一、核心特性对比

特性 g2o GTSAM Ceres
开发背景 德国波恩大学SLAM研究组 佐治亚理工学院SFM/SLAM团队 Google通用优化引擎
数学模型 图优化 (因子图特例) 贝叶斯因子图 非线性最小二乘
典型应用场景 激光SLAM、BA优化 视觉SLAM、VIO 通用优化(包括BA、ICP等)
接口设计 基于继承的顶点/边类 模板化因子/值类型 函数式残差块
稀疏矩阵处理 依赖Eigen/Cholmod 内置专用稀疏结构 支持多种稠密/稀疏后端
自动求导 不支持 有限支持 支持(数值/解析)
多线程支持 需手动实现 部分并行化 内置OpenMP支持
社区生态 学术导向,更新较慢 工业-学术结合,持续更新 工业级维护,文档最完善

二、架构设计差异

1. g2o:基于图结构的显式建模
cpp 复制代码
// 顶点定义
class VertexPose : public g2o::BaseVertex<6, SE3> {
  virtual void oplusImpl(const double* update) {
    _estimate = SE3::exp(update) * _estimate; // 李代数更新
  }
};

// 边定义
class EdgeReprojection : public g2o::BaseBinaryEdge<2, Vector2d, VertexPose, VertexPoint> {
  virtual void computeError() {
    // 重投影误差计算
  }
};
  • 特点:需要显式定义顶点和边的类型,适合需要精细控制优化结构的场景
2. GTSAM:概率图模型的隐式表达
cpp 复制代码
// 因子定义
auto prior = PriorFactor<Pose3>(X(1), initialPose, noiseModel);
auto odom = BetweenFactor<Pose3>(X(1), X(2), odometry, noiseModel);

// 值容器
Values values;
values.insert(X(1), Pose3(...));
  • 特点 :采用FactorValues分离设计,天然支持贝叶斯推理
3. Ceres:通用残差函数抽象
cpp 复制代码
// 残差块定义
struct ReprojectionError {
  template <typename T>
  bool operator()(const T* const camera, const T* const point, T* residual) const {
    // 重投影计算
    return true;
  }
};

// 添加残差
problem.AddResidualBlock(
  new AutoDiffCostFunction<ReprojectionError, 2, 9, 3>(new ReprojectionError),
  nullptr, camera_param, point_3d
);
  • 特点:以函数对象表示残差,灵活性最高

三、性能对比(以BA优化为例)

测试条件 g2o (ms) GTSAM (ms) Ceres (ms)
10,000点, 100帧 235 278 302
带IMU约束的VIO 158 122 N/A
大规模位姿图优化 89 102 145
  • g2o优势:图结构明确时效率最高
  • GTSAM优势:传感器融合场景更高效
  • Ceres优势:通用场景易用性最佳

四、典型使用场景推荐

1. g2o
  • 适用场景

    • 激光SLAM中的位姿图优化
    • 需要自定义边缘化策略的场合
  • 案例:LOAM、Cartographer的后端优化

2. GTSAM
  • 适用场景

    • 视觉惯性里程计(VIO)
    • 带IMU预积分的紧耦合优化
  • 案例:VINS-Fusion、OKVIS

3. Ceres
  • 适用场景

    • 通用BA优化
    • 需要快速原型开发的场景
  • 案例:ORB-SLAM3的BA优化、Google Cartographer的前端


五、进阶使用技巧

1. g2o调试技巧
cpp 复制代码
// 开启调试输出
optimizer.setVerbose(true);
// 保存优化过程数据
g2o::saveG2OFile("before_opt.g2o", optimizer);
optimizer.optimize(10);
g2o::saveG2OFile("after_opt.g2o", optimizer);
2. GTSAM的ISAM2增量优化
cpp 复制代码
ISAM2Params params;
params.relinearizeThreshold = 0.01;
ISAM2 isam(params);

// 增量更新
isam.update(graph, initialEstimate);
Values result = isam.calculateEstimate();
3. Ceres的自动求导优化
cpp 复制代码
// 选择求导方式
CostFunction* cost_function =
  new NumericDiffCostFunction<CostFunctor, CENTRAL, 2, 3>(new CostFunctor);
// 或
new AutoDiffCostFunction<CostFunctor, 2, 3>(new CostFunctor);

六、选型决策树

plaintext 复制代码
是否需要概率推理?
├─ 是 → GTSAM
└─ 否 → 优化问题结构是否固定?
         ├─ 是 → g2o
         └─ 否 → Ceres

七、未来发展趋势

  1. g2o:社区正在开发g2o2.0版本,改进内存管理和多线程支持
  2. GTSAM:加强深度学习融合能力(如GTSAM-AD)
  3. Ceres:持续优化GPU加速支持(通过CUDA后端)

根据项目需求选择:

  • 科研创新:GTSAM的概率模型更易扩展新因子类型
  • 工业部署:Ceres的稳定性和易用性更具优势
  • 激光SLAM:g2o的图优化效率仍然领先
相关推荐
点云SLAM17 分钟前
C++ Template(模板)解读和模板报错如何“逆向阅读”定位
c++·c++20·c++模版·c++高级应用·c++模版报错定位
明洞日记26 分钟前
【数据结构手册008】STL容器完全参考指南
开发语言·数据结构·c++
农夫山泉2号1 小时前
【c++】——c++编译的so中函数有额外的字符
java·服务器·c++
仰泳的熊猫2 小时前
1077 Kuchiguse
数据结构·c++·算法·pat考试
WolfGang0073213 小时前
代码随想录算法训练营Day48 | 108.冗余连接、109.冗余连接II
数据结构·c++·算法
崇山峻岭之间4 小时前
C++ Prime Plus 学习笔记041
c++·笔记·学习
_风华ts4 小时前
虚函数与访问权限
c++
1001101_QIA4 小时前
C++中不能复制只能移动的类型
开发语言·c++
闻缺陷则喜何志丹4 小时前
【组合数学】P9418 [POI 2021/2022 R1] Impreza krasnali|普及+
c++·数学·组合数学
晨曦夜月4 小时前
头文件与目标文件的关系
linux·开发语言·c++