面包屑图标 当前位置: 首页
AI资讯
热点详情

SLAM优化算法中图优化与凸优化的核心区别解析

AI热点日报
AI热点日报时间:2026-07-08
热点解读

小白:师兄师兄,我最近在钻研 SLAM 中的优化算法时,遇到了一个叫“图优化”的方法。回想以前还学过“凸优化”,这两个名字听起来好像,应该不是同一个概念吧?师兄:哈哈,你这个问题问得真有水平!虽然中文读音一模一样,但含义天差地别。我们来看英文表达——图优化是 graph optimization 或

小白:师兄师兄,我最近在钻研 SLAM 中的优化算法时,遇到了一个叫“图优化”的方法。回想以前还学过“凸优化”,这两个名字听起来好像,应该不是同一个概念吧?

师兄:哈哈,你这个问题问得真有水平!虽然中文读音一模一样,但含义天差地别。我们来看英文表达——图优化是 graph optimization 或 graph-based optimization,这里的“图”指的是数据结构中的 graph;而凸优化是 convex optimization,这里的“凸”指的是凸函数。所以光看英文就能轻松区分开。

小白:原来如此!我看 SLAM 里图优化用得非常广泛,也翻过高博的书,但还是一头雾水,求师兄科普一下啊。

师兄:图优化确实是个重要工具,概念其实并不复杂,主要是编程实现时稍微有点绕。

小白:太同意了……那个代码看得我简直怀疑人生。

图优化有什么优势?

师兄:按照老规矩,先聊聊图优化的由来。SLAM 后端通常有两条技术路线:一条是以扩展卡尔曼滤波(EKF)为代表的滤波方法,另一条是以图优化为代表的非线性优化方法。目前 SLAM 研究的主流热点几乎都围绕图优化展开。

小白:滤波方法很早就被提出来了,前人的研究也很深入。那为什么现在图优化成了主流呢?

师兄:你说得没错。滤波方法(尤其 EKF)在 SLAM 发展的很长一段历史里一直占据主导地位,早期大牛们设计了各种滤波器来提升效果,那时候入门 SLAM,EKF 是必修课。简单总结一下滤波方法的优缺点:

优点:在当年计算资源有限、待估计量比较简单的情况下,EKF 等滤波方法相当有效,经常被用在激光 SLAM 中。

缺点:一个明显的短板是存储量会随着状态量呈平方增长——因为要存储协方差矩阵,所以不适用于大型场景。而如今的视觉 SLAM 会涉及大量路标点(特征点),数据量极大,滤波方法根本扛不住,效率极低。

小白:原来是这样。那图优化在视觉 SLAM 中的效率真的很高吗?

师兄:说来话长。不到十年前(感觉还挺久的),大家仍普遍使用滤波方法,因为图优化里的 Bundle Adjustment(以下简称 BA)虽然起到了核心作用,但那时包含大量特征点和相机位姿的 BA 计算量巨大,根本无法实时运行。

小白:啊?那后来发生了什么?(聚精会神听故事中)

师兄:后来研究者们发现,视觉 SLAM 尽管包含大量特征点和相机位姿,但 BA 实际上是稀疏的——稀疏就有办法加速啊!比较有代表性的是 2009 年,几位大神发表了《SBA:A software package for generic sparse bundle adjustment》,再加上计算机硬件发展迅猛,基于图优化的视觉 SLAM 终于可以实现实时运算了!

小白:太厉害了!向大牛们致敬!

图优化是什么?

小白:既然图优化是主流,那我能不能跳过滤波方法直接学图优化呢?反正滤波方法也看不太懂……

师兄:嗯,图优化确实是主流,以后有需要再回去看滤波方法也行。今天咱们就专注讲图优化好啦。

小白:好嘞,那问题来了:到底什么是图优化?

师兄:图优化里的“图”就是数据结构中的图——一个图由若干个顶点(vertex)以及连接这些顶点的边(edge)组成。举个例子:

一个机器人在房间里移动,它在某个时刻 t 的位姿(pose)就是一个顶点,这也是待优化的变量。位姿之间关系就构成一条边,比如时刻 t 和时刻 t+1 之间的相对位姿变换矩阵就是一条边,边通常代表误差项。

在 SLAM 中,图优化一般分解成两个任务:

1. 构建图:机器人位姿作为顶点,位姿间的约束关系作为边。

2. 优化图:调整机器人的位姿(顶点)来尽量满足边的约束,使得误差最小化。

下面是一个直观的例子。根据机器人位姿(来自编码器或 ICP 匹配)作为图的顶点,图的边就是位姿之间的关系。由于误差存在,机器人建立的地图其实是不准确的(如下图左)。通过设置边的约束,图优化会朝着满足边约束的方向进行优化,最终得到一个优化后的地图(如下图中间),它与真实地图(下图右)非常接近。

小白:哇塞,这个效果也太明显了!刚开始误差那么大,最后全都被校正过来了。

师兄:是啊,所以图优化在 SLAM 中举足轻重,必须掌握!

小白:好,感觉动力满满!咱们开始进入编程模式吧!

先了解 g2o 框架

师兄:前面简单介绍了图优化,你也看到了它的强大能力。那具体怎么编程实现呢?

小白:对啊,有没有现成的库啊?我还只是个“调包侠”。

师兄:这个必须有!在 SLAM 领域,基于图优化的一个非常流行的框架就是 g2o,它是 General Graphic Optimization 的缩写,是一个用来优化非线性误差函数的 C++ 框架。这个库足以满足你调包侠的梦想~

小白:哈哈,太好了,不然打死我也写不出来啊!那这个 g2o 具体怎么用?

师兄:先说安装。g2o 安装很简单,参考 GitHub 官网:https://github.com/RainerKuemmerle/g2o,按步骤操作即可。注意安装前要确认电脑上已经装好了第三方依赖。

小白:好,看起来挺好装的。不过问题是,我看相关的代码感觉特别复杂,不知从何下手。

师兄:别急,第一次接触 g2o 确实会有这种感觉,而且官方文档写得也不算“通俗易懂”。但如果你能理清它的框架,再去看代码,应该很快就能上手。

小白:没错,必须先把框架了然于胸,不然就算勉强看懂别人的代码,自己也不会写啊!

师兄:嗯嗯。其实 g2o 已经帮我们实现了许多内部算法,只是在构建时需要遵循一些规则。这完全可以接受——毕竟一个程序不可能满足所有需求,所以以后用 g2o 时还需要多看多记,才能更好地驾驭这个库。

小白:记住了。养成记笔记的好习惯,还要多练习。

师兄:好,那先看下面这张图,这是 g2o 的基本框架结构。在查资料时很多地方都能看到。看图时要注意箭头类型。

1. 图的核心

小白:师兄,这个图该从哪里开始看?感觉东西好多……

师兄:想知道哪个最重要,就看看箭头源头在哪里。

小白:我看看……好像是最左侧的 SparseOptimizer?

师兄:对了。SparseOptimizer 是整个图的核心。注意右上角的 is-a 实心箭头——这个 SparseOptimizer 是一个 Optimizable Graph,从而也是一个超图(HyperGraph)。

小白:我去,师兄,怎么突然冒出这么多奇怪的术语,都是啥意思啊?

师兄:不需要一个个全都搞懂,不然黄花菜都凉了。暂时只了解名字就好,有些以后用不上,有些以后用到再回来看。遇到重要的我会详细解释。

小白:好。那下一步看哪里?

2. 顶点和边

师兄:先看上面的结构。注意 has-many 箭头——超图包含许多顶点(HyperGraph::Vertex)和边(HyperGraph::Edge)。这些顶点继承自 Base Vertex,也就是 OptimizableGraph::Vertex;边可以继承自 BaseUnaryEdge(单边)、BaseBinaryEdge(双边)或 BaseMultiEdge(多边),它们都叫做 OptimizableGraph::Edge。

小白:头有点晕了,师兄。

师兄:哈哈,不用一个个记,现阶段了解这些就行。顶点和边在编程中很重要,关于它们的定义以后会详细说。下面看底部的结构。

小白:嗯嗯,知道啦!

3. 配置 SparseOptimizer 的优化算法和求解器

师兄:看下面——整个图的核心 SparseOptimizer 包含一个优化算法(OptimizationAlgorithm)的对象。OptimizationAlgorithm 通过 OptimizationWithHessian 来实现,其中迭代策略可以从 Gauss-Newton(高斯牛顿法,GN)、Levenberg-Marquardt(LM 法)、Powell's dogleg 三者中选一个(常用的是 GN 和 LM)。

小白:GN 和 LM 就是我们以前讲过的非线性优化方法中常用的那两种吧。

4. 如何求解

师兄:那么如何求解?OptimizationWithHessian 内部包含一个求解器(Solver),这个 Solver 实际由一个 BlockSolver 组成。BlockSolver 有两个部分:一个是 SparseBlockMatrix,用于计算稀疏的雅可比和 Hessian 矩阵;一个是线性方程的求解器(LinearSolver),用于计算迭代过程中最关键的一步 HΔx=−b。LinearSolver 有几种方法可选:PCG、CSparse、Cholmod,具体定义后面会介绍。

到此,就是上面那张图的简单理解。

一步步带你看懂 g2o 编程流程

小白:师兄,看完了我还是不知道编程时具体该怎么写!

师兄:我正要讲这个。首先需要说明:梳理顺序是从顶层到底层,但编程实现时需要反过来——就像建房子一样,从底层开始搭建框架一直到顶层。g2o 的整个框架就是按下图中标的顺序来写的。

高博在十四讲中用 g2o 求解曲线参数的例子来说明,源代码地址:https://github.com/gaoxiang12/slambook/edit/master/ch6/g2o_curve_fitting/main.cpp

为了方便理解,我重新加了注释,如下所示:

typedef g2o::BlockSolver< g2o::BlockSolverTraits<3,1> > Block;  // 每个误差项优化变量维度为3,误差值维度为1
// 第1步:创建一个线性求解器LinearSolver
Block::LinearSolverType* linearSolver = new g2o::LinearSolverDense();
// 第2步:创建BlockSolver。并用上面定义的线性求解器初始化
Block* solver_ptr = new Block( linearSolver );
// 第3步:创建总求解器solver。从GN, LM, DogLeg中选一个,再用上述块求解器BlockSolver初始化
g2o::OptimizationAlgorithmLevenberg* solver = new g2o::OptimizationAlgorithmLevenberg( solver_ptr );
// 第4步:创建终极大boss 稀疏优化器(SparseOptimizer)
g2o::SparseOptimizer optimizer;     // 图模型
optimizer.setAlgorithm( solver );   // 设置求解器
optimizer.setVerbose( true );       // 打开调试输出
// 第5步:定义图的顶点和边。并添加到SparseOptimizer中
CurveFittingVertex* v = new CurveFittingVertex();
v->setEstimate( Eigen::Vector3d(0,0,0) );
v->setId(0);
optimizer.addVertex( v );
for ( int i=0; isetId(i);
  edge->setVertex( 0, v );
  edge->setMeasurement( y_data[i] );
  edge->setInformation( Eigen::Matrix::Identity()*1/(w_sigma*w_sigma) );
  optimizer.addEdge( edge );
}
// 第6步:设置优化参数,开始执行优化
optimizer.initializeOptimization();
optimizer.optimize(100);

结合上面的流程图和代码,下面一步步解释具体步骤。

1. 创建一个线性求解器 LinearSolver

我们要求解的增量方程形式是:H△X=-b。通常情况下,直接求逆就是 △X=-H.inv*b。看起来很简单,但这有个前提——H 的维度较小,矩阵求逆就能解决问题。但当 H 的维度较大时,矩阵求逆变得很困难,求解问题也变得很复杂。

小白:那有什么办法吗?

师兄:办法肯定是有的。此时我们需要一些特殊方法对矩阵进行求逆。下面这张图是 GitHub 上 g2o 相关部分的代码:

点进去可以分别查看每个方法的解释。如果不想挨个点进去,看看下面的总结就行:

  • LinearSolverCholmod:使用 sparse cholesky 分解法,继承自 LinearSolverCCS
  • LinearSolverCSparse:使用 CSparse 法,继承自 LinearSolverCCS
  • LinearSolverPCG:使用 preconditioned conjugate gradient 法,继承自 LinearSolver
  • LinearSolverDense:使用 dense cholesky 分解法,继承自 LinearSolver
  • LinearSolverEigen:依赖项只有 eigen,使用 eigen 中 sparse Cholesky 求解,编译好后可以方便地在其他地方使用,性能和 CSparse 差不多,继承自 LinearSolver

2. 创建 BlockSolver,并用上面定义的线性求解器初始化

BlockSolver 内部包含 LinearSolver,用上面定义的线性求解器来初始化。它的定义在如下文件夹内:g2o/g2o/core/block_solver.h

点进去会发现 BlockSolver 有两种定义方式:

一种是指定固定变量的 solver,来看定义:using BlockSolverPL = BlockSolver< BlockSolverTraits >; 其中 p 代表 pose 的维度(注意一定是流形 manifold 下的最小表示),l 表示 landmark 的维度。

另一种是可变尺寸的 solver,定义如下:using BlockSolverX = BlockSolverPL;

小白:为何会有可变尺寸的 solver 呢?

师兄:因为某些场景下,Pose 和 Landmark 在程序开始时并不能确定,此时块状求解器没法固定变量,使用可变尺寸的 solver,所有参数都在中间过程中被确定。

另外,block_solver.h 的最后预定义了比较常用的几种类型:

  • BlockSolver_6_3:表示 pose 是6维,观测点是3维,用于3D SLAM中的BA
  • BlockSolver_7_3:在 BlockSolver_6_3 基础上多了一个 scale
  • BlockSolver_3_2:表示 pose 是3维,观测点是2维

以后遇到,知道这些数字是什么意思就行了。

3. 创建总求解器 solver,从 GN、LM、DogLeg 中选一个,再用块求解器 BlockSolver 初始化

g2o/g2o/core/ 目录,发现求解器的优化方法有三种:高斯牛顿(GaussNewton)法、LM(Levenberg–Marquardt)法、Dogleg 法,如下图所示,也和前面的图匹配。

小白:师兄,上图最后那个 OptimizationAlgorithmWithHessian 是干嘛的?

师兄:点进 GN、LM、Doglet 算法内部,会发现它们都继承自同一个类:OptimizationWithHessian,如下图所示,也和我们最前面那张图相符。

然后点进 OptimizationAlgorithmWithHessian,发现它又继承自 OptimizationAlgorithm,也和前面相符。

总之,在该阶段可选的三种方法:

  • g2o::OptimizationAlgorithmGaussNewton
  • g2o::OptimizationAlgorithmLevenberg
  • g2o::OptimizationAlgorithmDogleg

4. 创建终极大 boss 稀疏优化器(SparseOptimizer),并用已定义求解器作为求解方法

创建稀疏优化器:g2o::SparseOptimizer optimizer;

用前面定义好的求解器作为求解方法:SparseOptimizer::setAlgorithm(OptimizationAlgorithm* algorithm)

其中 setVerbose 是设置优化过程输出信息用的:SparseOptimizer::setVerbose(bool verbose)

来看它的定义:

5. 定义图的顶点和边,并添加到 SparseOptimizer 中

这部分比较复杂,下一次再介绍。

6. 设置优化参数,开始执行优化

设置 SparseOptimizer 的初始化、迭代次数、保存结果等。

初始化:SparseOptimizer::EdgeSet& eset

设置迭代次数,然后就开始执行图优化:SparseOptimizer::optimize(int iterations, bool online)

小白:终于搞明白 g2o 流程了!谢谢师兄!必须给你个「好看」啊!

热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:SLAM优化算法中图优化与凸优化的核心区别解析要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://m.elecfans.com/article/1921182.html
机器人 SLAM

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-08 20:13
Craftman AI聊天机器人构建工具

最近留意到一款AI聊天机器人构建工具——Craftman,它的核心思路很有意思:让企业或个人能用自己已有的数据来训练ChatGPT,然后直接嵌入到网站上做智能客服或问答助手。简单来说,就是把通用大模型变成你的专属知识库响应系统。什么是Craftman?Craftman是一个AI聊天机器人构建平台,允

AI热点2026-07-08 20:13
Vidu长视频AI大模型一键生成16秒1080P高清视频

如果告诉你,现在借助AI技术就能一键生成时长16秒、分辨率达1080P的高清视频,并且画面流畅自然、物理规律真实可信,你是不是觉得有些不可思议?事实上,这就是Vidu——由中国生数科技与清华大学联合打造的全球首个长时长、高一致性、高动态性视频大模型。它采用独创的Diffusion与Transform

AI热点2026-07-08 20:13
Hansei通过AI聊天帮助用户高效便捷简化知识库访问流程

想象一下,你拥有一个庞大而复杂的知识库,里面堆满了各类文档、PDF文件以及YouTube视频教程。过去想要查找某份资料,往往需要翻遍目录、反复尝试关键词搜索,效率低下令人困扰。如今,借助Hansei这款知识库管理工具,一切变得轻松高效——你只需像与朋友聊天一样,用自然语言提出需求,AI助手就能从你的

AI热点2026-07-08 20:13
Blinkn ChatGPT智能购物助手

Blinkn是基于ChatGPT的智能电商购物助手,具备语义理解、精准产品推荐与比较、多语言支持等功能,可与主流平台无缝集成并个性化定制,提供7×24小时实时客服,高效解决购物疑问,显著减少决策摩擦,提升转化率与用户体验。

延伸阅读