1. 直接法的思想
我们在<LK光流法跟踪特征点>这篇文章介绍了如何跟踪某个像素并形成轨迹。事实上跟踪这些特征点的最终目的还是为了计算相机的位置和姿态变化。今天我们要介绍的直接法就是不先计算像素的轨迹而是直接计算出相机的位置和姿态。直接法的思想是:“同一个块它的灰度值是不会发生变化的(这和光流法非常像)。比如说我们相机绕着一个球去拍摄。那么时刻t的这帧里面球所在的那块像素的灰度值,与它在时刻t+dt这帧图片中球所在的那块像素灰度值相同。唯一变化的是球所在的那个像素块在图片中的相对位置发生了变化。变化了的原因是因为相机的位置和姿态发生了变化。我们要做的是求出相机怎么位置和姿态怎么发生了怎样的变化。那么怎么求呢?我们先假设相机发生了某种变化R,假设球在时刻t的那帧图片中的位置是p1(看看后面那张图)。那么在t+dt时刻那帧图片中球的位置就是p2=Rp1。现在已知p1和p2处的像素灰度值一样,要求得R。我们可以遍历R的各种取值,如何评价这个取值好不好呢?我只需要比对用选定的那个R计算出的p2那个地方的灰度值与p1处的灰度值是否接近。直接法的思想就是这么简单。”。我们知道LK光流法它是需要先提取特征点,但是直接法是不需要提取特征点的所以计算复杂度更低适合嵌入式这种计算资源有限的场合。
2. 直接法的推导
2.1误差模型
我们假设相机发生了某种旋转和平移变换,旋转矩阵是R平移量是t。我们可以用一个变换矩阵T来表示旋转R+平移t。我们要做到的就是求出T。根据什么求出T?根据第1帧上p1所在的那块像素的灰度值,应该与第2帧p2所在的那个块的像素的灰度值一样来计算矩阵T。那p1与p2又是什么关系?答:是同一个物体在不同视角下拍摄到的像素块。举个例子解释下:假设p1那个像素块是个球,我希望相机进行了变换T之后(p1那个点就变成了p2=Tp1),我希望p2这个像素块也是个球。当然我们只会比对p1和p2这两块像素灰度值是否一样。很明显这是个优化问题,因为T设置一个值,那么就会计算出一个p2。计算出一个p2那么我就得看看它是否是与p1那个块足够相似。我们假设p1与p2之间的灰度值误差是:error(T)=I1(p1)−I2(p2)=I1(p1)−I2(Tp1)。我们就是要从T的不同取值中找一个不错的解来最小化这个误差。此时的这个T就是相机发生的位置和姿态变换矩阵。
接下来要做的事就是根据误差模型求解最优的T,我们可以用高斯牛顿法或者列文伯格方法求解到让error(T)最小的T。
2.2求解让误差最小的变换矩阵T
而这两种方法不管是哪一种都是要求e(T)对变换矩阵T的导数。对这个随时间变化的矩阵求导这个可不是平常我们简简单单的求导。这要用到李群求导的知识。变换矩阵T就是一个李群(可以视作一个指数函数e(ξ∧)),它的自变量是ξ∧(李群的自变量叫做李代数)。也就是说T=e(ξ∧).于是误差函数变为:
error(T)=error(e(ξ∧))=I(p1)−I(e(ξ∧)p1)。对李群求导一般是用定义法求导数(被叫做李代数上的扰动模型,因为定义法求导就是李代数加上一个微小的增量,这个增量被视作是一个微小扰动)。即用e(ξ∧+Δξ∧)来替换原先的e(ξ∧)。
(下面这部分是参考高翔博士写的,但是他这部分写得过渡性不够好,比较难理解。然后我补充了泰勒展开的细节
于是误差模型就变成了:
error(e(ξ∧+Δξ∧))=I(p1)−I(e(ξ∧+Δξ∧)p1)=I(p1)−I(eξ∧eΔξ∧p1)对eΔξ∧在0处进行泰勒展开得≈I(p1)−I(e(ξ∧)(1+Δξ∧)p1)=I(p1)−I(e(ξ∧)p1+e(ξ∧)eΔξ∧p1)
注意:然后我们对I(e(ξ∧)p1+e(ξ∧)eΔξ∧p1)在e(ξ∧)p1处(进行一阶泰勒展开即把e(ξ∧)p1视作常数,Δξ视作自变量)得到:
=I(p1)−I(e(ξ∧)p1)−de(ξ∧)eΔξ∧p1dIdΔξde(ξ∧)eΔξ∧p1Δξ
也就是说误差模型变成了:
error(e(ξ∧+Δξ∧))=error(e(ξ∧))−de(ξ∧)eΔξ∧p1dIdΔξde(ξ∧)eΔξ∧p1Δξ
然后根据定义法求导:
limΔξ∧error(e(ξ∧+Δξ∧))−error(e(ξ∧)
参考文献:
[1] https://blog.csdn.net/Kevin_cc98/article/details/70920700
[2] https://www.cnblogs.com/gaoxiang12/p/5689927.html#mjx-eqn-eqjacobianofDirect
[3] https://arxiv.org/pdf/1607.02565.pdf