解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 4 讲 李群与李代数 (下)

2024-06-05 17:38

本文主要是介绍解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 4 讲 李群与李代数 (下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇解读中《解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 4 讲 李群与李代数 (上)》,我们先介绍了李群的定义,知道了我们前面介绍的旋转矩阵集合就是一个李群,然后我们通过一些推导得到了 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ),知道了旋转矩阵可以用李代数(向量)的形式去表示。
  
  这一讲我将带你解读李群和李代数的指数和对数运算,以及李代数的求导与扰动模型。

解读

指数映射与对数映射

前面我们经过不懈的努力找到了旋转矩阵另外的表示方法, R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ),但是我们并不知道这个 e x p ( ϕ ∧ ) exp(\boldsymbol\phi^{\wedge}) exp(ϕ)应该怎么计算。下面我们就跟着作者的思路一起学习一下。
  
  我要再次跟你强调一下 ϕ \boldsymbol\phi ϕ是一个四元数,它实际上也是一个三维向量,这一点请你别忘记了!同时你也别忘记 ϕ ∧ \boldsymbol\phi^{\wedge} ϕ表示的是反对称矩阵,虽然前面已经说过了,但是再强调一下。
  首先我们对 e x p ( ϕ ∧ ) exp(\boldsymbol\phi^{\wedge}) exp(ϕ)写成泰勒级数的方式: e x p ( ϕ ∧ ) = ∑ n = 0 ∞ 1 n ! ( ϕ ∧ ) n (0) exp(\boldsymbol\phi^{\wedge})=\sum_{n=0}^{\infty} \frac 1 {n!}(\boldsymbol\phi^{\wedge})^n\tag 0 exp(ϕ)=n=0n!1(ϕ)n(0)因为 ϕ \boldsymbol\phi ϕ是一个向量,我们可以把它写成 ϕ = θ a ⃗ \boldsymbol\phi=\theta\vec a ϕ=θa a ⃗ \vec a a 是和 ϕ \boldsymbol\phi ϕ方向相同的单位向量, θ \theta θ ϕ \boldsymbol\phi ϕ的模长。
  书中说到,对于 a ⃗ \vec a a ,有两条性质, a ⃗ ∧ ∗ a ⃗ ∧ = a ⃗ ∗ a ⃗ T − I (1) \vec a^{\wedge}*\vec a^{\wedge} = \vec a * \vec a^T - I \tag1 a a =a a TI(1) a ⃗ ∧ ∗ a ⃗ ∧ ∗ a ⃗ ∧ = − a ⃗ ∧ (2) \vec a^{\wedge}*\vec a^{\wedge}*\vec a^{\wedge} = -\vec a^{\wedge} \tag2 a a a =a (2)然后我们就可以把(0)式进行展开了,并且应用上(1)(2)的性质 e x p ( ϕ ∧ ) = e x p ( θ a ⃗ ∧ ) = ∑ n = 0 ∞ 1 n ! ( θ a ⃗ ∧ ) n (3) exp(\boldsymbol\phi^{\wedge})=exp(\theta\vec a^{\wedge})=\sum_{n=0}^{\infty} \frac 1 {n!}(\theta\vec a^{\wedge})^n \tag3 exp(ϕ)=exp(θa )=n=0n!1(θa )n(3)上式(3)拆开之后进行化简(具体过程请看书本),可以得到如下式子: e x p ( ϕ ∧ ) = e x p ( θ a ⃗ ∧ ) = c o s θ I + ( 1 − c o s θ ) a ⃗ a ⃗ T + s i n θ a ⃗ ∧ (4) exp(\boldsymbol\phi^{\wedge})=exp(\theta\vec a^{\wedge})=cos\theta I+(1-cos\theta)\vec a\vec a^T+sin\theta\vec a^{\wedge}\tag4 exp(ϕ)=exp(θa )=cosθI+(1cosθ)a a T+sinθa (4)握草,(4)式不就是我们第三讲说的罗德里格斯公式吗!?怎么搞了一大圈又回到原点了!?
  
  我们上面的推导没有问题啊!那我们来仔细回味一下这些推导过程到底得到了什么结论。我们首先把旋转矩阵转换成了对应的李代数形式,即就是 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ),然后求得了这个指数映射关系实际上就是罗德里格斯公式。我们上一讲运用罗德里格斯公式的时候,主要是用来把旋转向量转换成旋转矩阵。我们仔细观察(4)式, θ a ⃗ \theta\vec a θa 不就等于是旋转向量嘛!那是不是可以这样认为,旋转矩阵对应的李代数实际上就是旋转向量组成的空间?答案是:肯定的!
  
  上面的思维转换有一点难,我们不妨再不厌其烦的总结一下:我们一开始从 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ)入手,等式左边的 R R R是李群,等式右边的 ϕ \boldsymbol\phi ϕ是它对应的李代数,然后去探索这个指数映射的解法。惊奇的发现这个指数映射其实就是通过罗德里格斯公式变换过去的。而罗德里格斯公式也是将旋转向量转换成旋转矩阵的公式。所以我们可以得出一个结论,旋转矩阵群对应的李代数,实际上就是旋转向量组成的集合。也就是说旋转矩阵的李代数就是旋转向量。哇,看来前面这么多内容只是将第三讲的内容升华到了更高的理论层上,实际上也并没有什么新的东西产生。于是乎,我们得到了一个结论,第四讲一大部分东西都是忽悠人的,现在看来确实是这样的,哈哈,开个玩笑。
  
  当我们明白了旋转矩阵的指数映射之后,理解变换矩阵 T T T的指数映射似乎也就顺理成章了,所以不再解读,大家看书即可!如果上面的内容你还觉得思维转不过来,请结合书本多看几遍。
  
  既然有旋转向量到旋转矩阵的指数映射,那也就有旋转矩阵到旋转向量的对数映射,书中直接给出了对数映射的公式,大家请参考课本《十四讲》!

BCH公式与近似形式

还记得我们一开始说的,为什么要引入李群和李代数吗?目的就是为了后面在优化过程中就行求导。
  
  我们说旋转矩阵不满足加法封闭,那我们通过指数映射 R = e x p ( ϕ ∧ ) R = exp(\boldsymbol\phi^{\wedge}) R=exp(ϕ)变换到李代数的形式,在李代数的形式下,我们是否可以求导呢?让我们来探讨一下:
  
  如果我们想要能求导,那就必须能够对加法运算封闭,如果我们旋转矩阵相乘对应到李代数是相加,那我们就可以通过李代数的方式进行求导。也就是说要下式(5)成立 e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) = e x p ( ϕ 1 ∧ + ϕ 2 ∧ ) (5) exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge})=exp(\boldsymbol\phi_1^{\wedge}+\boldsymbol\phi_2^{\wedge})\tag5 exp(ϕ1)exp(ϕ2)=exp(ϕ1+ϕ2)(5) l n ( e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) ) = ϕ 1 ∧ + ϕ 2 ∧ (6) ln(exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge}))=\boldsymbol\phi_1^{\wedge}+\boldsymbol\phi_2^{\wedge}\tag6 ln(exp(ϕ1)exp(ϕ2))=ϕ1+ϕ2(6)显然对于标量,(5)(6)式是成立的,但是对于矩阵(5)(6)式不成立。
  等式(6)在对矩阵进行运算的时候,是满足 BCH公式, l n ( e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) ) = ϕ 1 ∧ + ϕ 2 ∧ + 1 2 [ ϕ 1 ∧ , [ ϕ 1 ∧ , ϕ 2 ∧ ] ] + . . . ln(exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge}))=\boldsymbol\phi_1^{\wedge}+\boldsymbol\phi_2^{\wedge}+\frac 1 2[\boldsymbol\phi_1^{\wedge},[\boldsymbol\phi_1^{\wedge},\boldsymbol\phi_2^{\wedge}]]+... ln(exp(ϕ1)exp(ϕ2))=ϕ1+ϕ2+21[ϕ1,[ϕ1,ϕ2]]+...,BCH告诉我们,在做矩阵运算时会产生余项。
  考虑到,SLAM是实际问题,所以我们可以做一些近似,我们把小量中二次以上的项都忽略掉。此时(6)式可以近似等于如下表达: l n ( e x p ( ϕ 1 ∧ ) e x p ( ϕ 2 ∧ ) ) ∨ ≈ { J l ( ϕ 2 ) − 1 ϕ 1 + ϕ 2 当 ϕ 1 为 小 量 J r ( ϕ 1 ) − 1 ϕ 2 + ϕ 1 当 ϕ 2 为 小 量 (7) ln(exp(\boldsymbol\phi_1^{\wedge})exp(\boldsymbol\phi_2^{\wedge}))^{\vee}\approx \begin{cases}J_l(\boldsymbol\phi_2)^{-1}\boldsymbol\phi_1+\boldsymbol\phi_2 当\boldsymbol\phi_1为小量\\J_r(\boldsymbol\phi_1)^{-1}\boldsymbol\phi_2+\boldsymbol\phi_1 当\boldsymbol\phi_2为小量\end{cases}\tag 7 ln(exp(ϕ1)exp(ϕ2)){Jl(ϕ2)1ϕ1+ϕ2 ϕ1Jr(ϕ1)1ϕ2+ϕ1 ϕ(7)通过(7)式我们就可以得到,李群乘法(旋转矩阵乘法)与李代数加法(旋转向量)的关系了。
  现在我们来考虑一个实际情况,某一个旋转 R R ,对应的李代数 ϕ \boldsymbol\phi ϕ,如果在它左边乘上一个微小的旋转 Δ R \Delta R ΔR Δ R \Delta R ΔR对应的李代数是 Δ ϕ \Delta\boldsymbol\phi Δϕ。根据(7)式中的第一个等式,可以得到: e x p ( Δ ϕ ) e x p ( ϕ ) = e x p ( ( ϕ + J l − 1 Δ ϕ ) ∧ ) (8) exp(\Delta\boldsymbol\phi)exp(\boldsymbol\phi)=exp((\boldsymbol\phi+J_l^{-1}\Delta\boldsymbol\phi)^{\wedge})\tag8 exp(Δϕ)exp(ϕ)=exp((ϕ+Jl1Δϕ))(8)上式(8)就告诉我们了,旋转向量加法和旋转矩阵乘法的关系。注意:我并没有介绍 J J J怎么计算,请看书中给出的公式。
  反过来,当我们做李代数的加法时,对应到李群上面是怎样的运算呢?可以由下式给出: e x p ( ( ϕ + Δ ϕ ) ∧ ) = e x p ( ( J l − 1 Δ ϕ ) ∧ ) e x p ( ϕ ∧ ) = e x p ( ϕ ∧ ) e x p ( ( J r − 1 Δ ϕ ) ∧ ) (9) exp((\boldsymbol\phi+\Delta\boldsymbol\phi)^{\wedge})=exp((J_l^{-1}\Delta\boldsymbol\phi)^{\wedge})exp(\boldsymbol\phi^{\wedge})=exp(\boldsymbol\phi^{\wedge})exp((J_r^{-1}\Delta\boldsymbol\phi)^{\wedge})\tag{9} exp((ϕ+Δϕ))=exp((Jl1Δϕ))exp(ϕ)=exp(ϕ)exp((Jr1Δϕ))(9)

对位姿有关函数的求导问题

对于旋转矩阵和变换矩阵,它们对加法都没有良好的定义,所以对姿态有关的函数求导,只能通过李代数进行。关于用李代数解决求导问题,有两种思路:

  • 用李代数表示姿态,然后根据李代数加法对李代数进行求导;
  • 对李群左乘或者右乘微小扰动,然后对该扰动求导。

我们分别来看这两种求导方法的区别:

李代数的求导

假设我们要对前后两个时刻的姿态求导数,因为旋转矩阵没有加法,所以我们就对旋转矩阵的李代数就行求导,如下式: ∂ ( e x p ( ϕ ∧ ) ) ∂ ϕ (10) \frac {\partial(exp(\boldsymbol\phi^{\wedge}))}{\partial\boldsymbol\phi}\tag{10} ϕ(exp(ϕ))(10)上式根据导数定义进行求导: ∂ ( e x p ( ϕ ∧ ) ) ∂ ϕ = lim ⁡ δ ϕ → 0 e x p ( ( ϕ + δ ϕ ) ∧ ) − e x p ( ϕ ∧ ) δ ϕ \frac{\partial(exp(\boldsymbol\phi^{\wedge}))}{\partial\boldsymbol\phi} = \lim_{\delta\boldsymbol\phi \to 0}\frac{exp((\boldsymbol\phi+\delta\boldsymbol\phi)^{\wedge})-exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} ϕ(exp(ϕ))=δϕ0limδϕexp((ϕ+δϕ))exp(ϕ)对上式使用BCH线性近似,得到: = lim ⁡ δ ϕ → 0 e x p ( ( J l δ ϕ ) ∧ ) e x p ( ϕ ∧ ) − e x p ( ϕ ∧ ) δ ϕ =\lim_{\delta\boldsymbol\phi \to 0}\frac{exp((J_l\delta\boldsymbol\phi)^{\wedge})exp(\boldsymbol\phi^{\wedge})-exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} =δϕ0limδϕexp((Jlδϕ))exp(ϕ)exp(ϕ)对上式的 e x p ( ( J l δ ϕ ) ∧ ) exp((J_l\delta\boldsymbol\phi)^{\wedge}) exp((Jlδϕ))进行泰勒展开取常数项和一次项,得到下式: ≈ lim ⁡ δ ϕ → 0 e x p ( I + ( J l δ ϕ ) ∧ ) e x p ( ϕ ∧ ) − e x p ( ϕ ∧ ) δ ϕ \approx\lim_{\delta\boldsymbol\phi \to 0}\frac{exp(I+(J_l\delta\boldsymbol\phi)^{\wedge})exp(\boldsymbol\phi^{\wedge})-exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} δϕ0limδϕexp(I+(Jlδϕ))exp(ϕ)exp(ϕ) = lim ⁡ δ ϕ → 0 ( J l δ ϕ ) ∧ e x p ( ϕ ∧ ) δ ϕ =\lim_{\delta\boldsymbol\phi \to 0}\frac{(J_l\delta\boldsymbol\phi)^{\wedge}exp(\boldsymbol\phi^{\wedge})}{\delta\boldsymbol\phi} =δϕ0limδϕ(Jlδϕ)exp(ϕ)上式中,将反对称符号看做是叉积,交换两项的叉积顺序,然后变号: = lim ⁡ δ ϕ → 0 − ( e x p ( ϕ ∧ ) ) ∧ J l δ ϕ δ ϕ =\lim_{\delta\boldsymbol\phi \to 0}\frac{-(exp(\boldsymbol\phi^{\wedge}))^{\wedge}J_l\delta\boldsymbol\phi}{\delta\boldsymbol\phi} =δϕ0limδϕ(exp(ϕ))Jlδϕ = − ( R ) ∧ J l =-(R)^{\wedge}J_l =(R)Jl通过上面的过程我们得到了旋转矩阵相对于李代数的求导: ∂ R ∂ ϕ = ∂ ( e x p ( ϕ ∧ ) ) ∂ ϕ = − ( R ) ∧ J l \frac {\partial R}{\partial\boldsymbol\phi}=\frac {\partial(exp(\boldsymbol\phi^{\wedge}))}{\partial\boldsymbol\phi}=-(R)^{\wedge}J_l ϕR=ϕ(exp(ϕ))=(R)Jl书中说到 J l J_l Jl的计算很复杂,所以求导时候,并不采用这种方法,而是采用下面介绍的扰动模型的方法。

扰动模型(左乘)

以左乘为例,我们在对 R R R左乘一个微小量 Δ R \Delta R ΔR,就可以得到下一个姿态为 Δ R ∗ R \Delta R*R ΔRR,我们设这左扰动的李代数为 φ \boldsymbol\varphi φ,然后再次使用导数定义对 ∂ R ∂ φ \frac {\partial R}{\partial\boldsymbol\varphi} φR进行求导:
∂ R ∂ ϕ = lim ⁡ φ → 0 e x p ( φ ∧ ) ∗ e x p ( ϕ ∧ ) − e x p ( ϕ ∧ ) φ \frac {\partial R}{\partial\boldsymbol\phi} = \lim_{\boldsymbol\varphi \to 0} \frac {exp(\boldsymbol\varphi^{\wedge})*exp(\boldsymbol\phi^{\wedge}) - exp(\boldsymbol\phi^{\wedge})} {\boldsymbol\varphi} ϕR=φ0limφexp(φ)exp(ϕ)exp(ϕ)
与前面的思路一样,先对 e x p ( φ ∧ ) exp(\boldsymbol\varphi^{\wedge}) exp(φ)进行泰勒展开,然后保留低阶项,最终可以得到如下结论:
∂ R ∂ ϕ = − ( R ) ∧ (11) \frac {\partial R}{\partial\boldsymbol\phi} =-(R)^{\wedge} \tag{11} ϕR=(R)(11)
两种求导的方法,至于哪个精度更高,说实话还得就实际情况才能知道,但是扰动模型,显然计算量上要少非常多。
  
  同样的,变换矩阵的李代数求导,也可以类比获得,直接看书上的结论就可以了!
注意:不管是李代数求导还是扰动模型,都是旋转矩阵对李代数的求导,请你仔细观察一下!

实践

实践部分,请注意一定要使用作者Github上提供的Sophus库,不要使用Sophus官方的库,因为现在Sophus已经是模板类的方法编写的了,书中的例子已经不能直接使用最新版本的Sophus。

题外话:说实话这一讲,有一点儿难,特别是其中的证明特别多,而且概念之间的跳跃也很大,理解上来说是需要时间的,我已经尽量省去了很多不必要的内容,但是还是显得有点乱,你在学习的时候,如果实在不能理解证明过程,请先记住结论,但是在记住结论的同时,你要知道这个公式是用来干啥的。就像我们不知道电脑是怎么生产出来的,但是我们会用就行了。

人生在勤,不索何获 ——张衡

这篇关于解读《视觉SLAM十四讲》,带你一步一步入门视觉SLAM—— 第 4 讲 李群与李代数 (下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033731

相关文章

MySQL中的锁和MVCC机制解读

《MySQL中的锁和MVCC机制解读》MySQL事务、锁和MVCC机制是确保数据库操作原子性、一致性和隔离性的关键,事务必须遵循ACID原则,锁的类型包括表级锁、行级锁和意向锁,MVCC通过非锁定读和... 目录mysql的锁和MVCC机制事务的概念与ACID特性锁的类型及其工作机制锁的粒度与性能影响多版本

Redis过期键删除策略解读

《Redis过期键删除策略解读》Redis通过惰性删除策略和定期删除策略来管理过期键,惰性删除策略在键被访问时检查是否过期并删除,节省CPU开销但可能导致过期键滞留,定期删除策略定期扫描并删除过期键,... 目录1.Redis使用两种不同的策略来删除过期键,分别是惰性删除策略和定期删除策略1.1惰性删除策略

Redis与缓存解读

《Redis与缓存解读》文章介绍了Redis作为缓存层的优势和缺点,并分析了六种缓存更新策略,包括超时剔除、先删缓存再更新数据库、旁路缓存、先更新数据库再删缓存、先更新数据库再更新缓存、读写穿透和异步... 目录缓存缓存优缺点缓存更新策略超时剔除先删缓存再更新数据库旁路缓存(先更新数据库,再删缓存)先更新数

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

MCU7.keil中build产生的hex文件解读

1.hex文件大致解读 闲来无事,查看了MCU6.用keil新建项目的hex文件 用FlexHex打开 给我的第一印象是:经过软件的解释之后,发现这些数据排列地十分整齐 :02000F0080FE71:03000000020003F8:0C000300787FE4F6D8FD75810702000F3D:00000001FF 把解释后的数据当作十六进制来观察 1.每一行数据