NOTE / 2019/3/7

[ORB-SLAM2]卡方分布(Chi-squared)外点(outlier)剔除

SLAM技术笔记SLAMVIO传感器融合

outlier、外点、野值会严重影响SLAM的精度,因此必须把它们剔除。常用的做法是,计算一个误差,当这个误差大于设定阈值的时候就认为其为外点。那么,问题来了, 误差怎么算?阈值怎么选?

误差

就特征点法的视觉SLAM而言,一般会计算重投影误差。具体而言,记 u\mathbf{u} 为特征点的2D位置, uˉ\mathbf{ \bar u} 为由地图点投影到图像上的2D位置。重投影误差为

e=u−uˉ         (1)\mathbf{e}=\mathbf u - \mathbf{\bar u} \ \ \ \ \ \ \ \ \ (1)\\

重投影误差服从高斯分布

e∼N(0,Σ)         (2)\mathbf{e} \sim \mathcal N(\mathbf0, \mathbf\Sigma) \ \ \ \ \ \ \ \ \ (2) \\

其中,协方差 Σ\mathbf \Sigma 一般根据特征点提取的金字塔层级确定。具体的,记提取ORB特征时,图像金字塔的每层缩小尺度为 ss (ORB-SLAM中为1.2)。在ORB-SLAM中假设第0层的标准差为 pp 个pixel (ORB-SLAM中设为了1个pixel);那么,一个在金字塔第 nn 层提取的特征的重投影误差的协方差为

Σ=(sn×p)2[1001]         (3)\mathbf \Sigma = {\left( {{s^n} \times p} \right)^2}\left[ {\begin{array}{c} 1&0 \\ 0&1 \end{array}} \right] \ \ \ \ \ \ \ \ \ (3)\\

回头再看一下式(1)中的误差是一个2维向量,阈值也不好设置吧。那就把它变成一个标量,计算向量的内积 rr (向量元素的平方和)。但是,这又有一个问题,不同金字塔层的特征点都用同一个阈值,是不是不合理呢。于是,在计算内积的时候,利用协方差进行加权(协方差表达了不确定度)。那么就有了

r=eTΣ−1e         (4)r = \mathbf e^T \mathbf \Sigma ^{-1} \mathbf e \ \ \ \ \ \ \ \ \ (4)\\

利用协方差加权,起到了归一化的作用。具体的(4)式,可以变为

r=(Σ−12e)T(Σ−12e)         (5)r = (\mathbf \Sigma^{-\frac{1}{2}} \mathbf e)^{T} (\mathbf \Sigma^{-\frac{1}{2}} \mathbf e) \ \ \ \ \ \ \ \ \ (5) \\

而

(Σ−12e)∼N(0,I)(\mathbf \Sigma^{-\frac{1}{2}} \mathbf e) \sim \mathcal N (\mathbf 0, \mathbf I) \\

为多维标准正太分布。也就是说不同金字塔层提取的特征,计算的重投影误差都被归一化了,或者说去量纲化了,白化了。。。那么,我们只用一个阈值就可以了。(注意这里的 r≥0r\geq0 )

阈值

误差的问题已经解决了,下面的问题是如何选择阈值。式(5)可以看做两个独立的服从标准正太分布随机变量的平方和,它服从2个自由度的Chi-squared distribution卡方分布。以下是WIKI对卡方分布的解释。

In probability theory and statistics, the chi-squared distribution (also chi-square or χ2-distribution) with k degrees of freedom is the distribution of a sum of the squares of k independent standard normal random variables.

卡方分布的自由度即为向量的维度。不同的自由度卡方分布的概率密度函数和概率

文章配图几种自由度的卡方分布概率密度,摘自https://en.wikipedia.org/wiki/Chi-squared_distribution

文章配图几种自由度的卡方分布的概率分布 摘自https://en.wikipedia.org/wiki/Chi-squared_distribution

记概率分布(累积分布函数)为 α=F(x)\alpha = F(x) 。给定一个 α\alpha 可以确定一个区间 [0, F−1(α)][0,\ F^{-1}(\alpha)] 。可以认为, rr 落在这个区间内,则为内点,落在这个区间外则为外点。 F−1(α)F^{-1}(\alpha) 就是我们要找的阈值 xx 。

{内点 r<x外点 r⩾x , x=F−1(α)\left\{ {\begin{array}{l} {{\text{内点 }}r < x } \\ {{\text{外点 }}r \geqslant x {\text{ }}} \end{array}} \right.,{\text{ }}x = {F^{ - 1}}\left( \alpha \right)\\

一般取 α\alpha 为95%,一个内点只有5%的可能被错误的认为是外点。关于 F−1(α)F^{-1}(\alpha) ,前人已经搞了一个表。

文章配图累积分布函数的逆函数表

ORB-SLAM2取 α=95%\alpha=95\% ,对应的单目投影为2自由度,因此阈值为5.99;对应的双目投影为3个自由度,因此阈值为7.81。下图为ORB-SLAM2中源码截图。

文章配图ORB-SLAM2, Optimizer.cc文件中,优化时,阈值的设置

文章配图ORB-SLAM2,LocalMapping.cc文件中,三角化点时,阈值设置

参考资料

[1] Hartley R, Zisserman A. Multiple View Geometry in Computer Vision[M]. 2003.

[2] WIKI, Chi-squared_distribution

----更多SLAM文章----

杨小东:[ORB-SLAM2] ORB特征提取策略对ORB-SLAM2性能的影响

杨小东:[PR-3]ArUco EKF SLAM 扩展卡尔曼SLAM

杨小东:[PR-2] PF 粒子滤波/蒙特卡罗定位

----相关代码----

ydsf16 - Overview