学习MSCKF笔记——前端、图像金字塔光流、Two Point Ransac

  • 学习MSCKF笔记——前端、图像金字塔光流、Two Point Ransac
    • 1. 图像金字塔光流
    • 2. Two Point Ransac算法
    • 3. 新特征点提取

学习MSCKF笔记——前端、图像金字塔光流、Two Point Ransac

前段时间开始工作了,刚开始有点忙得缓不过来,调整了两三个月后总算有时间了,可以继续学点自己感兴趣的东西,写写博客。之前研究过一段时间VINS-Mono,那是一个后端优化框架的VIO,而MSCKF是基于滤波的框架,对于嵌入式平台会更加友好,因此想花点时间再学习下。目前我仅仅看了一遍paper,过了一遍代码,以及学习了几位前辈优秀的博客:
一步步深入了解S-MSCKF
MSCKF那些事(一)MSCKF算法简介
还有深蓝学院吴博的课程,我的这篇博客主要是我自己学习过程中的笔记,参考内容主要如上。

我学习的代码是msckf_vio,代码写得非常简介明了,读代码可以比较容易地总结出前端算法的流程图如下:

这里我主要对代码中的几个细节进行简单分析,包括图像金字塔光流、Two Point Ransac算法、新Fast特征点提取

1. 图像金字塔光流

光流法我们再熟悉不过了,MSCKF为了节省计算量,在图像输入时就对图像进行了金字塔操作,那么金字塔光流是如何实现的,收益是怎样的,下面先对金字塔光流进行推导。金字塔光流的参考论文为Pyramidal Implementation of the Lucas Kanade Feature Tracker Description of the algorithm.

我们知道光流法最基本的原理如下:I(x+Δx,y+Δy,t+Δt)−I(x,y,t)=∂I∂xΔx+∂I∂yΔy+∂I∂tΔtI(x+\Delta x, y+\Delta y, t+\Delta t) - I(x, y, t)=\frac{\partial I}{\partial x} \Delta x+\frac{\partial I}{\partial y} \Delta y+\frac{\partial I}{\partial t} \Delta tI(x+Δx,y+Δy,t+Δt)−I(x,y,t)=∂x∂I​Δx+∂y∂I​Δy+∂t∂I​Δt当Δt\Delta tΔt足够小时,有−∂I∂t=∂I∂xdxdt+∂I∂ydydt=∂I∂xu+∂I∂yv-\frac{\partial I}{\partial t}=\frac{\partial I}{\partial x} \frac{d x}{d t}+\frac{\partial I}{\partial y} \frac{d y}{d t}=\frac{\partial I}{\partial x} u+\frac{\partial I}{\partial y} v−∂t∂I​=∂x∂I​dtdx​+∂y∂I​dtdy​=∂x∂I​u+∂y∂I​v即−It=[IxIy][uv]-I_{t}=\left[\begin{array}{ll} I_{x} & I_{y} \end{array}\right]\left[\begin{array}{l} u \\ v \end{array}\right]−It​=[Ix​​Iy​​][uv​]其中Ix,IyI_x,I_yIx​,Iy​为像素梯度,u,vu, vu,v为像素运动速度,是我们要求的未知量。一个约束方程无法求解二元方程,因此就诞生Lucas-Kanade光流,假定邻域像素具备运动一致性,取邻域像素进计算求解:{I1xu+I1yv=−I1tI2xu+I2yv=−I2t⋯Inxu+Inyv=−In\left\{\begin{array}{l} I_{1 x} u+I_{1 y} v=-I_{1 t} \\ I_{2 x} u+I_{2 y} v=-I_{2 t} \\ \cdots \\ I_{n x} u+I_{n y} v=-I_{n} \end{array}\right.⎩⎪⎪⎨⎪⎪⎧​I1x​u+I1y​v=−I1t​I2x​u+I2y​v=−I2t​⋯Inx​u+Iny​v=−In​​令A=[[Ix,Iy]1⋮[Ix,Iy]k],b=[It1⋮Itk]\boldsymbol{A}=\left[\begin{array}{c} {\left[{I}_{x}, {I}_{y}\right]_{1}} \\ \vdots \\ {\left[{I}_{x}, {I}_{y}\right]_{k}} \end{array}\right], \boldsymbol{b}=\left[\begin{array}{c} {I}_{t 1} \\ \vdots \\ {I}_{t k} \end{array}\right]A=⎣⎢⎡​[Ix​,Iy​]1​⋮[Ix​,Iy​]k​​⎦⎥⎤​,b=⎣⎢⎡​It1​⋮Itk​​⎦⎥⎤​于是有[uv]∗=−(ATA)−1ATb\left[\begin{array}{c} u \\ v \end{array}\right]^{*}=-\left(\boldsymbol{A}^{T} \boldsymbol{A}\right)^{-1} \boldsymbol{A}^{T} \boldsymbol{b}[uv​]∗=−(ATA)−1ATb由于Lucas-Kanada光流取的是邻域像素,如果像素运动过快超出邻域就无法满足以上假设了,因此就诞生了金字塔光流法:使用低分辨率的图片来估计高分辨率图片像素的运动趋势
首先是构建高斯金字塔,所谓高斯金字塔就是通过高斯下采样构建的,如下图所示:

高斯下采样可以理解为先进行高斯模糊,再进行下采样的操作,通过高斯下采样图像尺寸为原尺寸的一半,原始图片在最底层(第0层),分辨率最低的图片在最顶层(第LmL_mLm​层)。我们假设第LLL层的光流的估计的某个像素的位移为gLg^LgL(估计值),那么第L−1L-1L−1层的光流估计的该像素的位移为:gL−1=2(gL+dL)g^{L-1} = 2 (g^{L}+d^{L})gL−1=2(gL+dL)其中dLd^LdL为根据第L−1L-1L−1层图像求得的修正量(修正值),具体的推到过程如下所示:
我们首先定义第LLL层像素邻域范围内的匹配误差和如下:ϵL(dL)=ϵL(dxL,dyL)=∑x=uxL−ωxuxL+ωx∑y=uyL−ωyuvL+ωy(IL(x,y)−JL(x+gxL+dxL,y+gyL+dyL))2\epsilon^{L}\left({d}^{L}\right)=\epsilon^{L}\left(d_{x}^{L}, d_{y}^{L}\right)=\sum_{x=u_{x}^{L}-\omega_{x}}^{u_{x}^{L}+\omega_{x}} \sum_{y=u_{y}^{L}-\omega_{y}}^{u_{v}^{L}+\omega_{y}}\left(I^{L}(x, y)-J^{L}\left(x+g_{x}^{L}+d_{x}^{L}, y+g_{y}^{L}+d_{y}^{L}\right)\right)^{2}ϵL(dL)=ϵL(dxL​,dyL​)=x=uxL​−ωx​∑uxL​+ωx​​y=uyL​−ωy​∑uvL​+ωy​​(IL(x,y)−JL(x+gxL​+dxL​,y+gyL​+dyL​))2其中,III和JJJ是前后两帧不同的图像,gxL,gyLg^L_x,g^L_ygxL​,gyL​是由上一层光流的估计值(gxL=2(dxL+1+dxL+1),gyL=2(gxL+1+dyL+1)g^L_x=2(d^{L+1}_x+d^{L+1}_x),g^L_y= 2(g^{L+1}_x+d^{L+1}_y)gxL​=2(dxL+1​+dxL+1​),gyL​=2(gxL+1​+dyL+1​)),dxL,dyLd^L_x,d^L_ydxL​,dyL​为当前层我们要求的的修正值。且我们假设最顶层(第LmL_mLm​层)的光流估计的估计值为gLm=[00]T{g}^{L_{m}}=\left[\begin{array}{ll} 0 & 0 \end{array}\right]^{T}gLm​=[0​0​]T接下来为了推到的方便,我们对上面的匹配误差和损失函数进行重写,令∀(x,y)∈[px−ωx−1,px+ωx+1]×[py−ωy−1,py+ωy+1],A(x,y)≐IL(x,y)\forall(x, y) \in\left[p_{x}-\omega_{x}-1, p_{x}+\omega_{x}+1\right] \times\left[p_{y}-\omega_{y}-1, p_{y}+\omega_{y}+1\right], A(x, y) \doteq I^{L}(x, y)∀(x,y)∈[px​−ωx​−1,px​+ωx​+1]×[py​−ωy​−1,py​+ωy​+1],A(x,y)≐IL(x,y)∀(x,y)∈[px−ωx,px+ωx]×[py−ωy,py+ωy],B(x,y)≐JL(x+gxL,y+gyL)\forall(x, y) \in\left[p_{x}-\omega_{x}, p_{x}+\omega_{x}\right] \times\left[p_{y}-\omega_{y}, p_{y}+\omega_{y}\right], B(x, y) \doteq J^{L}\left(x+g_{x}^{L}, y+g_{y}^{L}\right)∀(x,y)∈[px​−ωx​,px​+ωx​]×[py​−ωy​,py​+ωy​],B(x,y)≐JL(x+gxL​,y+gyL​)ν‾=[νx,νy]T=dL\overline{{\nu}}=\left[\nu_{x}, \nu_{y}\right]^{T}=\mathrm{d}^{L}ν=[νx​,νy​]T=dL那么我们要求的损失函数可以写为:ε(νˉ)=ε(νx,νy)=∑x=px−ωxpx+ωx∑y=py−ωypy+ωy(A(x,y)−B(x+νx,y+νy))2\varepsilon(\bar{\nu})=\varepsilon\left(\nu_{x}, \nu_{y}\right)=\sum_{x=p_{x}-\omega_{x}}^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left(A(x, y)-B\left(x+\nu_{x}, y+\nu_{y}\right)\right)^{2}ε(νˉ)=ε(νx​,νy​)=x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​(A(x,y)−B(x+νx​,y+νy​))2为了最小化损失函数,我们对损失函数进行求导:∂ε(νˉ)∂νˉ=−2∑x=px−ωxpx+ωx∑y=py−ωypy+ωy(A(x,y)−B(x+νx,y+νy))⋅[∂B∂x∂B∂y]\frac{\partial \varepsilon(\bar{\nu})}{\partial \bar{\nu}}=-2 \sum_{x=p_{x}-\omega_{x}}^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left(A(x, y)-B\left(x+\nu_{x}, y+\nu_{y}\right)\right) \cdot\left[\begin{array}{cc} \frac{\partial B}{\partial x} & \frac{\partial B}{\partial y} \end{array}\right]∂νˉ∂ε(νˉ)​=−2x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​(A(x,y)−B(x+νx​,y+νy​))⋅[∂x∂B​​∂y∂B​​]然后我们对B(x+νx,y+νy)B\left(x+\nu_{x}, y+\nu_{y}\right)B(x+νx​,y+νy​)进行泰勒展开,有:∂ε(νˉ)∂νˉ≈−2∑x=px−ωxpx+ωx∑y=py−ωypy+ωy(A(x,y)−B(x,y)−[∂B∂x∂B∂y]νˉ)⋅[∂B∂x∂B∂y]\frac{\partial \varepsilon(\bar{\nu})}{\partial \bar{\nu}} \approx-2 \sum_{x=p_{x}-\omega_{x} }^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left(A(x, y)-B(x, y)-\left[\begin{array}{cc} \frac{\partial B}{\partial x} & \frac{\partial B}{\partial y} \end{array}\right] \bar{\nu}\right) \cdot\left[\begin{array}{cc} \frac{\partial B}{\partial x} & \frac{\partial B}{\partial y} \end{array}\right]∂νˉ∂ε(νˉ)​≈−2x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​(A(x,y)−B(x,y)−[∂x∂B​​∂y∂B​​]νˉ)⋅[∂x∂B​​∂y∂B​​]接下来,我们令:δI(x,y)≐A(x,y)−B(x,y)\delta I(x, y) \doteq A(x, y)-B(x, y)δI(x,y)≐A(x,y)−B(x,y)∇I=[IxIy]≐[∂B∂x∂B∂y]T\nabla I=\left[\begin{array}{l} I_{x} \\ I_{y} \end{array}\right] \doteq\left[\begin{array}{cc} \frac{\partial B}{\partial x} & \frac{\partial B}{\partial y} \end{array}\right]^{T}∇I=[Ix​Iy​​]≐[∂x∂B​​∂y∂B​​]T其中Ix(x,y)=∂A(x,y)∂x=A(x+1,y)−A(x−1,y)2I_{x}(x, y)=\frac{\partial A(x, y)}{\partial x}=\frac{A(x+1, y)-A(x-1, y)}{2}Ix​(x,y)=∂x∂A(x,y)​=2A(x+1,y)−A(x−1,y)​Iy(x,y)=∂A(x,y)∂y=A(x,y+1)−A(x,y−1)2I_{y}(x, y)=\frac{\partial A(x, y)}{\partial y}=\frac{A(x, y+1)-A(x, y-1)}{2}Iy​(x,y)=∂y∂A(x,y)​=2A(x,y+1)−A(x,y−1)​
因此有12∂ε(νˉ)∂νˉ≈∑x=px−ωxpx+ωx∑y=py−ωypy+ωy(∇ITνˉ−δI)∇IT\frac{1}{2} \frac{\partial \varepsilon(\bar{\nu})}{\partial \bar{\nu}} \approx \sum_{x=p_{x}-\omega_{x}}^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left(\nabla I^{T} \bar{\nu}-\delta I\right) \nabla I^{T}21​∂νˉ∂ε(νˉ)​≈x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​(∇ITνˉ−δI)∇IT将具体参数代入得:12[∂ε(νˉ)∂νˉ]T≈∑x=px−ωxpx+ωx∑y=py−ωypy+ωy([Ix2IxIyIxIyIy2]νˉ−[δIIxδIIy])\frac{1}{2}\left[\frac{\partial \varepsilon(\bar{\nu})}{\partial \bar{\nu}}\right]^{T} \approx \sum_{x=p_{x}-\omega_{x}}^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left(\left[\begin{array}{cc} I_{x}^{2} & I_{x} I_{y} \\ I_{x} I_{y} & I_{y}^{2} \end{array}\right] \bar{\nu}-\left[\begin{array}{c} \delta I I_{x} \\ \delta I I_{y} \end{array}\right]\right)21​[∂νˉ∂ε(νˉ)​]T≈x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​([Ix2​Ix​Iy​​Ix​Iy​Iy2​​]νˉ−[δIIx​δIIy​​])令G≐∑x=px−ωxpx+ωx∑y=py−ωypy+ωy[Ix2IxIyIxIyIy2]G \doteq \sum_{x=p_{x}-\omega_{x}}^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left[\begin{array}{cc} I_{x}^{2} & I_{x} I_{y} \\ I_{x} I_{y} & I_{y}^{2} \end{array}\right]G≐x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​[Ix2​Ix​Iy​​Ix​Iy​Iy2​​]bˉ≐∑x=px−ωxpx+ωx∑y=py−ωypy+ωy[δIIxδIIy]\bar{b} \doteq \sum_{x=p_{x}-\omega_{x}}^{p_{x}+\omega_{x}} \sum_{y=p_{y}-\omega_{y}}^{p_{y}+\omega_{y}}\left[\begin{array}{c} \delta I I_{x} \\ \delta I I_{y} \end{array}\right]bˉ≐x=px​−ωx​∑px​+ωx​​y=py​−ωy​∑py​+ωy​​[δIIx​δIIy​​]
则有12[∂ε(νˉ)∂νˉ]T≈Gνˉ−bˉ\frac{1}{2}\left[\frac{\partial \varepsilon(\bar{\nu})}{\partial \bar{\nu}}\right]^{T} \approx G \bar{\nu}-\bar{b}21​[∂νˉ∂ε(νˉ)​]T≈Gνˉ−bˉ那我们最终要求的νˉ\bar{\nu}νˉ为:νˉ=G−1bˉ\bar{\nu}=G^{-1} \bar{b}νˉ=G−1bˉ这实际上就是求出了第LLL层图像的修正量dLd^LdL,结合估计值gLg^LgL就可以求出来下一层的估计值gL−1g^{L-1}gL−1,直到求导最底层,也就是我们原始图片的估计值。

2. Two Point Ransac算法

Two Point Ransac算是是原文作者提出来的一个新算法,算法的目的时在前后帧跟踪特征点时是筛选出前后帧匹配的outliers,在执行Two Point Ransac之前,先对当前帧追踪到的特征点进行双目匹配,去除掉一部分不满足双目极限约束的特征点。可以看到,虽然用的是双目相机,但是只对左目使用了光流法进行特征追踪,因此接下来的Two Point Ransac是对左右目共同使用的。

Two Point Ransc的流程是先通过IMU角速度均值乘以时间获得的前后帧旋转矩阵RRR,然后通过旋转矩阵RRR将上一帧的特征点投影到当前帧,这时上一帧的特征点和当前帧匹配的特征点之间就差一个平移ttt,用公式描述如下:
首先前后两帧之间的匹配点满足极线约束:p2T⋅[t]x⋅R⋅p1=0p_{2}^{T} \cdot[t]_{x} \cdot R \cdot p_{1}=0p2T​⋅[t]x​⋅R⋅p1​=0,通过旋转矩阵RRR将前一帧特征点投影到当前帧之后坐标分别为:R⋅p1=[x1y11]T,p2=[x2y21]TR \cdot p_{1}=\left[\begin{array}{lll} x 1 & y 1 & 1 \end{array}\right]^{T}, p_{2}=\left[\begin{array}{lll} x 2 & y 2 & 1 \end{array}\right]^{T}R⋅p1​=[x1​y1​1​]T,p2​=[x2​y2​1​]T,那么满足[x2y21]⋅[0−tztytz0−tx−tytx0]⋅[x1y11]=0\left[\begin{array}{ccc} x_{2} & y_{2} & 1 \end{array}\right] \cdot\left[\begin{array}{ccc} 0 & -t_{z} & t_{y} \\ t_{z} & 0 & -t_{x} \\ -t_{y} & t_{x} & 0 \end{array}\right] \cdot\left[\begin{array}{c} x_{1} \\ y_{1} \\ 1 \end{array}\right]=0[x2​​y2​​1​]⋅⎣⎡​0tz​−ty​​−tz​0tx​​ty​−tx​0​⎦⎤​⋅⎣⎡​x1​y1​1​⎦⎤​=0对其进行展开后[y1−y2−(x1−x2)x1y2−x2y2]⋅[txtytz]=0\left[\begin{array}{lll} y_{1}-y_{2} & -\left(x_{1}-x_{2}\right) & x_{1} y_{2}-x_{2} y_{2} \end{array}\right] \cdot\left[\begin{array}{l} t_{x} \\ t_{y} \\ t_{z} \end{array}\right]=0[y1​−y2​​−(x1​−x2​)​x1​y2​−x2​y2​​]⋅⎣⎡​tx​ty​tz​​⎦⎤​=0由于误差的存在,并不是所有匹配的特征点都会满足上面的等式,我们考虑两个点的情况有:[y1−y2−(x1−x2)x1y2−x2y2y3−y4−(x3−x4)x3y4−x4y3]⋅[txtytz]=[AxAyAz]T⋅[txtytz]≈[00]\left[\begin{array}{ccc} y_{1}-y_{2} & -\left(x_{1}-x_{2}\right) & x_{1} y_{2}-x_{2} y_{2} \\ y_{3}-y_{4} & -\left(x_{3}-x_{4}\right) & x_{3} y_{4}-x_{4} y_{3} \end{array}\right] \cdot\left[\begin{array}{c} t_{x} \\ t_{y} \\ t_{z} \end{array}\right]=\left[\begin{array}{c} A_{x} \\ A_{y} \\ A_{z} \end{array}\right]^{T} \cdot\left[\begin{array}{c} t_{x} \\ t_{y} \\ t_{z} \end{array}\right] \approx\left[\begin{array}{l} 0 \\ 0 \end{array}\right][y1​−y2​y3​−y4​​−(x1​−x2​)−(x3​−x4​)​x1​y2​−x2​y2​x3​y4​−x4​y3​​]⋅⎣⎡​tx​ty​tz​​⎦⎤​=⎣⎡​Ax​Ay​Az​​⎦⎤​T⋅⎣⎡​tx​ty​tz​​⎦⎤​≈[00​]平移向量有三个变量,两个点是无法求解的,因此将上面的式子拆解成如下三个式子:[AxAy]T⋅[txty]≈Az⋅tz[AxAz]T⋅[txtz]≈Ay⋅ty[AyAz]T⋅[tytz]≈Ax⋅tx\begin{array}{l} {\left[\begin{array}{c} A_{x} \\ A_{y} \end{array}\right]^{T} \cdot\left[\begin{array}{l} t_{x} \\ t_{y} \end{array}\right] \approx A_{z} \cdot t_{z}} \\ {\left[\begin{array}{c} A_{x} \\ A_{z} \end{array}\right]^{T} \cdot\left[\begin{array}{c} t_{x} \\ t_{z} \end{array}\right] \approx A_{y} \cdot t_{y}} \\ {\left[\begin{array}{c} A_{y} \\ A_{z} \end{array}\right]^{T} \cdot\left[\begin{array}{c} t_{y} \\ t_{z} \end{array}\right] \approx A_{x} \cdot t_{x}} \end{array}[Ax​Ay​​]T⋅[tx​ty​​]≈Az​⋅tz​[Ax​Az​​]T⋅[tx​tz​​]≈Ay​⋅ty​[Ay​Az​​]T⋅[ty​tz​​]≈Ax​⋅tx​​并添加尺度约束{if tx<ty&&tx<tz,then tx=1[−(x−x′),(xy′−x′y)][tytz]=−(y−y′){if ty<tx&&ty<tz,then ty=1[(y−y′),(xy′−x′y)][txtz]=(x−x′){if tz<tx&&tz<ty,then tz=1[(y−y′),−(x−x′)][txty]=−(xy′−x′y)\begin{aligned} &\left\{\begin{array}{l} \text { if } t_{x}<t_{y} \& \& t_{x}<t_{z}, \text { then } t_{x}=1 \\ {\left[-\left(x-x^{\prime}\right),\left(x y^{\prime}-x^{\prime} y\right)\right]\left[\begin{array}{c} t_{y} \\ t_{z} \end{array}\right]=-\left(y-y^{\prime}\right)} \end{array}\right.\\ &\left\{\begin{array}{l} \text { if } t_{y}<t_{x} \& \& t_{y}<t_{z}, \quad \text { then } t_{y}=1 \\ {\left[\left(y-y^{\prime}\right),\left(x y^{\prime}-x^{\prime} y\right)\right]\left[\begin{array}{c} t_{x} \\ t_{z} \end{array}\right]=\left(x-x^{\prime}\right)} \end{array}\right.\\ &\left\{\begin{array}{l} \text { if } t_{z}<t_{x} \& \& t_{z}<t_{y}, \quad \text { then } t_{z}=1 \\ {\left[\left(y-y^{\prime}\right),-\left(x-x^{\prime}\right)\right]\left[\begin{array}{c} t_{x} \\ t_{y} \end{array}\right]=-\left(x y^{\prime}-x^{\prime} y\right)} \end{array}\right. \end{aligned}​⎩⎨⎧​ if tx​<ty​&&tx​<tz​, then tx​=1[−(x−x′),(xy′−x′y)][ty​tz​​]=−(y−y′)​⎩⎨⎧​ if ty​<tx​&&ty​<tz​, then ty​=1[(y−y′),(xy′−x′y)][tx​tz​​]=(x−x′)​⎩⎨⎧​ if tz​<tx​&&tz​<ty​, then tz​=1[(y−y′),−(x−x′)][tx​ty​​]=−(xy′−x′y)​​
根据上面三个中的任意一个,我们就可以求出平移向量ttt,根据求解平移向量ttt我们求得各对匹配的特征点之间的误差,根据误差大小设定阈值就可以判断哪些特征点是outliers,哪些点是inliers,接下来我们整理下完整的RANSAC算法的流程:
(1)先从前后帧所有匹配点中随机选取两对匹配点进行上面的计算,获得平移向量ttt;
(2)通过平移向量ttt计算其他所有匹配点的误差,根据误差判定哪些是inlers,哪些是outliers;
(3)根据所有的inlers重新求得平移向量ttt;
(4)根据新的平移向量ttt计算所有匹配点的误差,若误差和小于之前RANSAC采样获得的最小误差,则将inliers和误差记录下来
(5)最终输出误差最小的inlers组合。
最后补一句,RANSC的迭代次数由用户需求的成功率和inlers比例确定,计算公式如下:M=log⁡(1−ps)log⁡(1−pK)M=\frac{\log \left(1-p_{s}\right)}{\log \left(1-p^{K}\right)}M=log(1−pK)log(1−ps​)​其中psp_sps​为RANSC成功率,ppp为inlers比例

3. 新特征点提取

新特征点提取过程中,为了保证提取的有效性,MSCKF采用了两种手段:
(1)在提取特征点是使用的Mask操作,这个操作在VINS-Mone中也使用了,不过VINS-Mono中使用的圆形,MSCKF中使用的是方形,这个可以参考我之前写过的博客:VINS-Mono关键知识点总结——前端详解,加不加Mask提取的特征点的效果会有很大差别的。
(2)就是将特征点分配到网格中进行管理,并根据响应进行排序,删除掉响应低的特征点,这样做可以提高特征点的有效性。

以上就是我学习前端时的一些关注点,因为也是在学习,难免会有理解不对的地方,如果有问题欢迎指出欢迎交流~下个礼拜写后端

此外,对其他SLAM算法感兴趣的同学可以看考我的博客SLAM算法总结——经典SLAM算法框架总结

学习MSCKF笔记——前端、图像金字塔光流、Two Point Ransac相关推荐

  1. 学习MSCKF笔记——后端、状态预测、状态扩增、状态更新

    学习MSCKF笔记--后端.状态预测.状态扩增.状态更新 学习MSCKF笔记--后端.状态预测.状态扩增.状态更新 1. 状态预测 2. 状态扩增 3. 状态更新 学习MSCKF笔记--后端.状态预测 ...

  2. 学习MSCKF笔记——真实状态、标称状态、误差状态

    学习MSCKF笔记--真实状态.标称状态.误差状态 学习MSCKF笔记--真实状态.标称状态.误差状态 1. 连续时间系统 1.1 真实状态运动学公式 1.2 标称状态运动学公式 1.3 误差状态运动 ...

  3. 学习MSCKF笔记——四元数基础

    学习MSCKF笔记--四元数基础 学习MSCKF笔记--四元数基础 1. 四元数基本性质 1.1 加法 1.2 乘法 1.3 共轭 1.4 模 1.5 逆 1.6 单位四元数 1.7 指数 1.8 对 ...

  4. cv2.error: opencv(4.4.0)_【从零学习OpenCV 4】图像金字塔

    点击上方"小白学视觉",选择"星标"公众号 重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习Open ...

  5. CV13 图像分辨率操作(图像金字塔与resize()函数)

    文章目录 1.图像金字塔的作用 2.高斯金字塔 2.1理论研究--分辨率缩小 2.2程序分析 2.3效果图 2.4拉普拉斯金字塔 3.图像缩放-resize()函数 3.1resize()函数介绍 3 ...

  6. opencv进阶学习笔记10:图像金字塔和图像梯度

    基础版笔记传送门: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 图像金字塔 变小 变大 原理 ...

  7. opencv学习笔记19:图像金字塔和图像拉普拉斯金字塔 (用于图像放大和缩小)

    图像金字塔原理 图像金字塔:只不同分辨率,不同尺寸子图构成的集合. 取样 向下取样:有一个图像G0,对它重新采样,得到分辨率小些的G1,以此类推. 向上取样:有一个图像G3,然后变成像素更多的G2,以 ...

  8. OpenCV学习笔记(十):图像金字塔Pyramid和图像缩放:pyrDown(),pyrUp(),resize()

    OpenCV学习笔记(十):图像金字塔Pyramid和图像缩放:pyrDown(),pyrUp(),resize() 一.图像金字塔定义: 图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是 ...

  9. opencv 的norm_OpenCV学习笔记(一)之图像金字塔-上采样与降采样与DOG

    一. 图像金字塔 一个图像金字塔式一系列的图像组成,最底下的图形尺寸最大,最上方的图像尺寸最小. 高斯金字塔是从底向上,逐层降采样得到的. 高斯金字塔的生成过程分为两步: 1. 对当前层进行高斯模糊. ...

最新文章

  1. vb.net 如何从文件中读取图像
  2. Cookie对象知识总结
  3. Golang——递归的使用
  4. python 安装中的错误解决
  5. Hurst exponent(赫斯特指数)代码与R/S值计算——python
  6. 苹果AirPods有望在年末推出新款产品 或将支持防水功能
  7. servlet跳转问题
  8. 【窗口置顶神器】DeskPins
  9. JavaScript特效之显示当前时间
  10. IP反向解析查询的方法
  11. CCSK认证,提升云安全专业技能,助力职业生涯发展
  12. android按键精灵兼容性,为什么逍遥android模拟器安装按键精灵总是出错
  13. 使用Enterprise Architect设计数据库-赋操作截图
  14. element ui的upload上传视频内容
  15. 桌面快捷方式异常——左下角附有问号怎么办
  16. 手把手教你如何高效落地单项目管理 | 一看既会
  17. jquery抓娃娃机代码
  18. Linux CentOS6和CentOS7设置静态ip
  19. 高德地图Javascript API设置域名白名单
  20. c51语言case是什么意思,单片机入门-C51语言switch-case语句电路应用实例

热门文章

  1. “面试不败计划”:集合知识整体总结
  2. org.activiti.engine.ActivitiException: Couldn't deserialize object in variable 'application'
  3. super关键字和final关键字
  4. 为什么安装Android SDK后无法安装flatform?
  5. spring boot配置文件:application.yml (yml与properties文件优缺对比)
  6. Eclipse导入项目常见问题----服务器版本问题02
  7. (Oracle学习笔记) sql*plus命令
  8. Android仿IOS的AssistiveTouch的控件EasyTouch实现
  9. Java/Android中实现Shell命令
  10. 简单示例,VS2019调试C语言程序