SLAM中的卡方分布


視覺slam中相鄰幀特征點匹配時,動輒上千個特征點,匹配錯誤的是難免的,而誤匹配勢必會對位姿精度以及建圖精度造成影響,那么如何分辨哪些是誤匹配的點對兒呢?如果已知兩幀的的單應矩陣,假設單應矩陣是沒有誤差的,那么兩幀中匹配正確的特征點通過單應矩陣是重投影是不應該有誤差的或者誤差十分小,而誤匹配的特征點的重投影誤差一定十分顯著。那么我們是不是可以設置一個誤差門限,從而甄別出這些誤匹配點?可是這個誤差門限該設置為多少?

假設圖像金字塔第n層中一個特征點\(\mathbf{p_c}=\begin{bmatrix}u \\ v\end{bmatrix}\)以及其對應的世界坐標系位置\(\mathbf{p_w}=\begin{bmatrix}x \\ y \\ z\end{bmatrix}\)和轉換矩陣\(T_{cw}\),將空間點重投影到圖像中為\(\mathbf{p_c'}=\begin{bmatrix}u' \\ v'\end{bmatrix}\)。那么x軸的重投影誤差\(e_x=u-u'\),假設變換矩陣沒有誤差,實際中由於不同時刻拍攝以及成像原因,會給重投影誤差帶來噪聲,不妨假設\(e_x\sim N(0,\sigma_x^2)\),同理假設\(e_y\sim N(0,\sigma_y^2)\),並假設噪聲方差\(\sigma_x^2=\sigma_y^2=(s^n\times n\_pixels)^2\)\(n\_pixels\)為噪聲所帶來的的像素誤差數,這里取值1,s為圖像金字塔的縮放因子,通常取1.2,有\(\sigma_x^2=\sigma_y^2=(s^n)^2\)顯然方差與特征點所處的層數有關。這里面表達了特征點所處的金字塔層數越高,重投影誤差的方差就越大。因此有\(\frac {1}{s^n}e_x\sim N(0,1),\frac {1}{s^n}e_y\sim N(0,1)\)

卡方分布

若k個隨機變量\(Z_1,Z_2,...,Z_k\)是相互獨立,符合標准正態分布的隨機變量(數學期望為0、方差為1),則隨機變量Z的平方和\(X=\sum_{i-1}^{k}Z_i^2\)被稱為服從自由度為 k 的卡方分布,記作\(X\sim\chi^2(k)\)
\(Z_1=\frac {1}{s^n}e_x,Z_2=\frac {1}{s^n}e_y,X=Z_1^2+Z_2^2\),根據卡方分布的定義,\(X\sim\chi^2(2)\),即2自由度的卡方分布。對於雙目匹配到的特征點在右圖中的x坐標為\(u_r'\),重投影后計算得到特征點左圖的x坐標\(u_l\),根據\(視差d=\frac {基線b*f_x}{深度}\),可以計算出視差從而得到重投影后右圖中特征點x坐標\(u_r=u_l-d\),得\(e_r=u_r'-u_r\)。同理\(\frac {1}{s^n}e_r\sim N(0,1)\),可構成卡方分布的另一個自由度,而\(X\)的物理意義就是各項誤差的平方和。

下圖為不同自由度卡方分布的概率密度函數和累積分布函數,分布函數記為\(F(X\leqslant x)=\alpha\)\(\alpha\)就是一個概率值,表示如果\(X\)服從卡方分布,那么\(X\)就有\(\alpha\)的概率值在\([0,x]\)中。如果已知\(\alpha\)的值,通過查表的方法我們可以找到對應的\(x\)值。比如2自由度的卡方分布,\(X\in [0,5.99]\)時,我們有95%的把握認為\(X\)是服從該分布的,以此將\(X>5.99\)的時候將該特征點排除。

下圖為卡方閾值與對應P值的查找表,可以簡單的認為\(P值=1-\alpha\)。具體解釋可以參考如何理解假設檢驗、P值?

實際代碼

// openvslam/module/two_view_triangulator.cc:95
// chi-squared values for p=5%
// (n=2)
constexpr float chi_sq_2D = 5.99146;
// (n=3)
constexpr float chi_sq_3D = 7.81473;

Vec2_t reproj_in_cur;
float x_right_in_cur;

camera->reproject_to_image(rot_cw, trans_cw, pos_w, reproj_in_cur, x_right_in_cur);

if (is_stereo) {
    const Vec2_t reproj_err = reproj_in_cur - keypt;
    const auto reproj_err_x_right = x_right_in_cur - x_right;
    if ((chi_sq_3D * sigma_sq) < (reproj_err.squaredNorm() + reproj_err_x_right * reproj_err_x_right)) {
        return false;
    }
}
else {
    const Vec2_t reproj_err = reproj_in_cur - keypt;
    if ((chi_sq_2D * sigma_sq) < reproj_err.squaredNorm()) {
        return false;
    }
}

上面的代碼reproject_to_image就是將3D點重投影回圖像中,reproj_err就是上文中的\(\begin{bmatrix}e_x \\ e_y\end{bmatrix},sigma\_sq=(s^n)^2\),reproj_err.squaredNorm()/sigma_sq就是\((\frac {1}{s^n})^2(e_x^2+e_y^2)=Z_1^2+Z_2^2=X\sim\chi^2(k)\)

參考

  1. [ORB-SLAM2]卡方分布(Chi-squared)外點(outlier)剔除
  2. https://en.wikipedia.org/wiki/Chi-squared_distribution


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM