VINS前端使用KLT稀疏光流跟踪算法(使用KLT特征点检测方法的LK跟踪算法)来跟踪抓取特征点(稀疏光流法只计算部分像素的运动,计算所有像素的称为稠密光流法)
KLT中的角点检测方法是用于满足LK光流法选择合适特征点的需求,LK光流法是通过先在前后两帧图像里分别建立一个固定大小窗口,然后找到让两个窗口间像素强度差的平方和最小的位移。然后将窗口内像素的移动近似为这样的位移向量(视所有像素移动都是这么移动)。然后实际上,一方面像素移动并不会那么简单,另一方面窗口内像素并不都是同样的移动方式,因为这样的近似必然会带来误差。而现在的问题就是如何去选择合适的窗口,或者特征点,从而获得最为精确的跟踪。KLT角点检测方法就是为了选择一个适合跟踪的特征点,它认为一个好的特征点的定义应当就是能被好的跟踪。
算法需要在以下三大假设才成立
1。亮度恒定(也可以说是灰度不变,假设在同一空间下图片中相同像素点的灰度值不变)
2.估计的两帧图片之间时间连续或者运动位移小。
3.假设某一个窗口内的所有像素具有相同的运动
1)像素点的光强度函数可以由其泰勒展开式表示,g指强度梯度,d指像素位移
2)计算出一个d值使窗口内偏差光强能量最小,即使其导数为0
从而我们可以得出Gd=e
由上式,我们就可以估计出位移向量d,显然这个估计是建立在窗口内的像素的是平滑(与粗糙相对)的,即其强度是一致的,而实际上这会在窗口内一些变化较大(如角点)的位置,造成其位移估计d偏差较大。然而可以通过迭代的方式,不断的应用新的d值,而图像块每次迭代都可以采用双线性插值(获得子像素精确度)得到新位置。
(3)下面最为重要的是这个角点的选择问题,这个角点是根据G矩阵的两个特征值来选择的,一方面两个特征值不能太小,排除噪声影响,另一方面两个特征值不能差别太大,说明这是角点。这里提出了下面的公式:
特征点的选择:首先将最小特征值降序排列,优先选择最小特征值大的。为了防止窗口重叠,如果发生选择的特征点在先前选择特征点的窗口内,就删除。最后再通过能量偏差函数删除。
对于特征值的说明,前一阵子没有具体搞懂特征值代表什么,经过这几天的查阅才知道,这是线性代数里的知识,对于矩阵A,存在一个实数Q,一个向量X,使得AX=QX,则矩阵的特征值为Q。