关于李群和李代数的理解

李群(Lie Group)和李代数(Lie Algebra)是SLAM、机器人学等领域中表示旋转/位姿的核心概念。
李群是"连续的群"比如旋转矩阵群SO(3)、位姿矩阵群SE(3),描述的是“最终的变换结果”。
李代数是李群在单位元处的切空间,描述的是“变换的增量/速度”。
一、先搞懂“群”:李群的基础
首先,“群”是一种数学结构,满足4个条件(封闭性、结合律、单位元、逆元),而李群是“光滑的、连续的群”简单理解就是:
比如旋转矩阵(3x3正交矩阵,行列式=1)构成的SO(3)群,任意两个旋转矩阵相乘还是旋转矩阵(封闭性),存在单位矩阵(无旋转),每个旋转矩阵都有逆矩阵(反向矩阵)。
比如位姿矩阵(4x4的SE(3)),也是李群,描述相机的位姿。
李群的核心特点:
1.描述"最终状态":比如SO(3)的一个元素(旋转矩阵),表示"从初始姿态旋转到某个姿态“的最终结果。
2.非欧几里得空间:SO(3)/SE(3)不是向量空间(比如旋转矩阵相加不再是旋转矩阵),无法直接做“增量更新”。
3.无加法运算:李群只有乘法(比如旋转矩阵相乘表示连续旋转),直接在李群上做优化会很麻烦。
二、李代数:解决李群"无法增量更新"的问题。
李代数式李群在“单位元”(比如SO(3)的单位矩阵,对应"无旋转")处的切空间,可以理解为:
李代数是向量空间(比如SO(3)对应的李代数是𝔰𝔬(3),是3维向量,也就是旋转向量/角轴)。
李代数描述的是“变换的增量”(比如𝔰𝔬(3)的一个3维向量[ωx, ωy, ωz],表示“绕某个轴旋转某个角度”的增量。
李代数支持加法(向量相加),完美适配优化算法(比如LM算法需要给变量加增量)。
三、李群和李代数之间通过两个核心函数转换:
指数映射(exp):李代数->李群(把"增量"变成"最终变换")
比如代码里的SO3d::exp(Vector3d(data_addr[0], data_addr[1], data_addr[2]))
把3维的旋转向量(李代数𝔰𝔬(3))转换成旋转矩阵(李群 SO (3)):
对数映射(log):李群->李代数(把“最终变换”拆成“增量”)
比如代码里的auto r = rotation.log();
把 SO (3) 旋转矩阵(李群)转换成旋转向量(李代数𝔰𝔬(3))。

点击查看代码
#include "sophus/se3.hpp"
#include "sophus/so3.hpp"
#include <Eigen/Core>
#include <iostream>
using namespace Sophus;
using namespace Eigen;
using namespace std;

int main()
{
    //1.定义李代数(3维旋转向量:绕z轴旋转90度,向量为[0,0,π/2])
    Vector3d so3_vector(0,0,M_PI/2);
    cout<<"李代数(旋转向量):"<<so3_vector.transpose()<<endl;

    //2.指数映射:李代数->李群(旋转矩阵)
    SO3d SO3_R=SO3d::exp(so3_vector);//SO(3)李群
    cout<<"李群(旋转矩阵):\n"<<SO3_R.matrix()<<endl;

    //3.对数映射:李群->李代数(还原旋转向量)
    Vector3d so3_vec2=SO3_R.log();
    cout<<"李群转回李代数:"<<so3_vec2.transpose()<<endl;

    //4.李群的乘法(连续旋转)vs李代数的加法(增量叠加)
    Vector3d delta_so3(0.1,0,0);//小增量(李代数)
    SO3d deta_SO3=SO3d::exp(delta_so3);//增量转李群
    SO3d new_SO3=deta_SO3*SO3_R;//李群乘法:给原旋转加增量
    cout<<"加增量后的旋转矩阵\n"<<new_SO3.matrix()<<endl;
    return 0;
}

运行结果

image

很多刚学李群 / 李代数的人都会有这个疑惑 —— 既然最终都是用李群相乘,那为啥还要绕一圈用李代数?
一句话核心答案:李群只能描述 “状态”,但优化算法需要 “增量”;李代数是连接 “优化需要的增量” 和 “李群合法状态” 的唯一桥梁,没有李代数,就没法在李群上做优化。
一、先戳破关键:优化算法的核心需求是 “加增量”,李群做不到
你代码里的 BA 优化,本质是最小化重投影误差,优化器(LM 算法)的核心逻辑是:
当前估计值 + 增量Δx → 新的估计值(更优)
这个 “+ 增量 Δx” 是优化的灵魂 —— 但李群(SO3/SE3)天生不支持 “+”,只支持 “×”,这就陷入了矛盾:
优化器只能输出 “向量形式的增量 Δx”(比如 3 维的旋转增量、6 维的位姿增量);
李群(旋转矩阵)无法直接 “加” 这个向量增量(加完就不是旋转矩阵了);
而李代数刚好解决这个矛盾:
1.优化器输出的 Δx 是李代数形式(3 维向量,属于欧几里得空间,能加);
2.把 Δx 通过exp转换成李群(小旋转矩阵);
3.用李群的乘法,把这个小旋转 “施加” 到原旋转上(保证结果还是合法的旋转矩阵)。
没有李代数的话,你连 “增量 Δx 该怎么表示” 都解决不了 —— 总不能让优化器直接输出一个 3×3 的旋转矩阵增量吧?且不说维度从 3 维变成 9 维(冗余),优化器也没法保证输出的增量矩阵乘到原矩阵上还是合法的旋转矩阵。
二、再看工程层面:李代数让优化更高效、更稳定

  1. 维度压缩,减少计算量
    李群 SO (3) 是 3×3 矩阵(9 个元素),但只有 3 个自由度(旋转的本质是绕轴转角度,3 维足够描述);
    李代数𝔰𝔬(3) 直接用 3 维向量表示(刚好匹配自由度),优化时只需要优化 3 个变量,而不是 9 个;
    同理,SE (3)(位姿)的李群是 4×4 矩阵(16 个元素),李代数𝔰𝔢(3) 是 6 维向量(3 旋转 + 3 平移),维度压缩一半以上,计算效率天差地别。
    相机顶点是 9 维(3 旋转 + 3 平移 + 1 焦距 + 2 畸变),其中旋转部分只用 3 维李代数表示 —— 如果用李群的 9 维,优化变量直接多 6 个,Hessian 矩阵规模暴增,BA 求解会慢到没法用。
  2. 避免数值奇异,保证优化稳定性
    李群的旋转矩阵要求 “正交且行列式 = 1”,但优化过程中如果直接操作李群,数值误差会导致矩阵逐渐偏离正交性(比如行列式从 1 变成 1.0001),最终优化发散;
    而李代数是 “无约束的向量”,优化时不需要考虑正交性 —— 只需要在每次更新后通过exp转回李群,就能自动保证旋转矩阵的合法性。这就像给优化加了 “安全锁”,永远不会出现非法的旋转状态。
    核心配合:优化器输出李代数增量 → exp 转李群 → 李群相乘更新状态 → log 转回李代数(供下一次优化),缺一不可。
posted @ 2026-02-10 11:44  阳光天气  阅读(57)  评论(0)    收藏  举报