SLAM--求解2D-2D图像间的运动

一、数学基础

1.1 反对称矩阵的性质

我们令 A = [ 0 − a 3 a 2 a 3 0 − a 1 − a 2 a 1 0 ] A=\left[ {\begin{matrix} 0&{ - {a_3}}&{{a_2}}\\ {{a_3}}&0&{ - {a_1}}\\ { - {a_2}}&{{a_1}}&0 \end{matrix}} \right] A=0a3a2a30a1a2a10,该矩阵是一个反对称矩阵,即 A T = − A A^T=-A AT=A;

利用 det ⁡ ( λ E − A ) = 0 \det(\lambda E-A)=0 det(λEA)=0来反对称矩阵A的特征值,化简得:
λ ( λ 2 + m ) = 0 ,            m = a 1 2 + a 2 2 + a 3 2 (1) \lambda(\lambda^2+m)=0, \;\;\;\;\;m=a_1^2+a_2^2+a_3^2\tag{1} λ(λ2+m)=0,m=a12+a22+a32(1)
特征多项式我们可以看出,这个 3 × 3 3\times3 3×3的矩阵的秩为2,有一个特征值为0,另外两个特征值相等且为虚数。


下面我们对反对称矩阵进行分解:

首先我们对于对称矩阵来说,如果矩阵 A A A是一个对称矩阵(在复数域上被称为Hermite矩阵),即 A T = A A^T=A AT=A,则存在一个正交矩阵 U ( U U T = U T U = I ) U(UU^T=U^TU=I) U(UUT=UTU=I),使得 A = U D U T A=UDU^T A=UDUT D D D为对角矩阵,另外 A A A不同特征值对应的特征向量正交;

返回到反对称矩阵上,若 S S S为反对称矩阵(在复数域上被称为反Hermite矩阵),存在正交矩阵 U U U,使得:
S = U B U T ,       B = κ ⋅ d i a g ( z 1 , z 2 , . . . , z m , 0 , 0 , . . . , 0 ) (2) S=UBU^T , \space \space \space \space \space B=\kappa \cdot diag(z_1,z_2,...,z_m,0,0,...,0)\tag{2} S=UBUT,     B=κdiag(z1,z2,...,zm,0,0,...,0)(2)
其中 κ \kappa κ为常数对角矩阵 κ = d i a g ( κ 1 , κ 2 , . . . , κ m , 0 , 0 , . . . , 0 ) \kappa = diag(\kappa_1,\kappa_2,...,\kappa_m,0,0,...,0) κ=diag(κ1,κ2,...,κm,0,0,...,0) z i = [ 0 1 − 1 0 ] , ( i = 1 , 2 , . . . , m ) z_i=\begin{bmatrix} 0 &1\\-1&0 \end{bmatrix},(i=1,2,...,m) zi=[0110],(i=1,2,...,m)

我们主要分析 3 × 3 3\times3 3×3的矩阵,令 S S S 3 × 3 3\times3 3×3的反对称矩阵,另外令:
W = [ 0 − 1 0 1 0 0 0 0 1 ] ,   Z = [ 0 1 0 − 1 0 0 0 0 0 ] (3) W=\begin{bmatrix} 0 &-1&0\\ \\1&0&0\\\\0&0&1 \end{bmatrix},\space Z=\begin{bmatrix} 0 &1&0\\ \\-1&0&0\\\\0&0&0 \end{bmatrix}\tag{3} W=010100001, Z=010100000(3)
根据上述性质,能够推出 S S S Z Z Z合同,即:
S = κ ⋅ U Z U T (4) S=\kappa \cdot UZU^T \tag{4} S=κUZUT(4)
为了在奇异值分解中构造奇异值 1,1,0,所以构造了正交矩阵 W W W,满足 Z = − d i a g ( 1 , 1 , 0 ) W = d i a g ( 1 , 1 , 0 ) W T Z=-diag(1,1,0)W =diag(1,1,0)W^T Z=diag(1,1,0)W=diag(1,1,0)WT,所以有:
S = − κ ⋅ U ⋅ d i a g ( 1 , 1 , 0 ) W ⋅ U T   或 者 S = κ ⋅ U ⋅ d i a g ( 1 , 1 , 0 ) W T ⋅ U T (5) \begin{aligned} S = -\kappa \cdot U\cdot diag(1,1,0)W\cdot U^T \\ ~\\或者 \quad S = \kappa \cdot U\cdot diag(1,1,0)W^T\cdot U^T \end{aligned}\tag{5} S=κUdiag(1,1,0)WUT S=κUdiag(1,1,0)WTUT(5)
参考文献: Multiple View Geometry in Computer Vision Second Edition. P258-259

接下来我们介绍奇异值分解;
 
 

1.2 奇异值分解

奇异值分解简单介绍,具体参考:奇异值分解(SVD)----作者:漫漫成长
 
对于一个矩阵 A m × n A_{m\times n} Am×n r a n k ( A ) = r   ( r ⩽ n , m ) rank(A)=r\space ({r\leqslant n,m}) rank(A)=r (rn,m),则 A T A A^TA ATA矩阵有 r r r个非零特征值 ( λ 1 , λ 2 , . . . , λ r ) (\lambda_1,\lambda_2,...,\lambda_r) (λ1,λ2,...,λr),存在两个正交矩阵 U , V U,V U,V,使得 A A A可以被分解为:
A = U S 0 V T , S = d i a g ( λ 1 , λ 2 , . . . , λ r , 0 , . . . , 0 ) n × n (6) A=US_0V^T,\quad S=diag(\lambda_1,\lambda_2,...,\lambda_r, 0,...,0)_{n \times n}\tag{6} A=US0VT,S=diag(λ1,λ2,...,λr,0,...,0)n×n(6)
S S S中的元素被称为 A A A的奇异值,其中 V V V A T A A^TA ATA特征值对应的单位特征向量, U U U A A T AA^T AAT特征值对应的单位特征向量。

由3阶反对称矩阵的特征值特点可以知道其奇异值一定是 d i a g ( σ , σ , 0 ) diag(\sigma,\sigma,0) diag(σ,σ,0)因为其有特征值0,以及两个相等的特征值

 
 

二、本质矩阵的推导

如图所示,我们需要通过不同的2D图像,利用相同的路标点(特征点),来推算相机之间的运动R和t,下面我们根据对极几何的特性进行推导。

我们假设存在着一个路标点 P w P_w Pw,对应两个不同相机位姿的像素坐标为 p 1 、 p 2 p_1、p_2 p1p2,分别对应着图像 I 1 和 I 2 I_1和I_2 I1I2 另外我们假设图像 I 1 I_1 I1对应的相机坐标与世界坐标重合(即 T 1 , w = E 4 × 4 T_{1,w}=\bm E_{4\times4} T1,w=E4×4)。

由相机模型可得:
s 1 p 1 = K T 1 , w P w = K P w   s 2 p 2 = K T 2 , w P w = K ( R P w + t ) (7) \begin{aligned} s_1\bm p_1&=\bm {KT_{1,w}P_w}=\bm {KP_w}\\~\\ s_2\bm p_2&=\bm{KT_{2,w}P_w}=\bm{K(RP_w+t)} \end{aligned}\tag{7} s1p1 s2p2=KT1,wPw=KPw=KT2,wPw=K(RPw+t)(7)
实际上, T 2 , w T_{2,w} T2,w也就是 T 2 , 1 T_{2,1} T2,1,即相机1到相机2的变换矩阵。

则有:
K − 1 p 1 = 1 s 1 P w   K − 1 p 2 = 1 s 2 ( R P w + t ) (8) \bm K^{-1}\bm p_1=\frac 1 {s_1}\bm P_w\\ ~\\ \bm K^{-1}\bm p_2=\frac 1 {s_2}\bm{(RP_w+t)} \tag{8} K1p1=s11Pw K1p2=s21(RPw+t)(8)

我们令:
x 1 = K − 1 p 1 , x 2 = K − 1 p 2 (9) \bm x_1=\bm K^{-1}\bm p_1,\quad \bm x_2=\bm K^{-1}\bm p_2\tag{9} x1=K1p1,x2=K1p2(9)
由公式可知, x 1 x_1 x1 x 2 x_2 x2是点 P w \bm P_w Pw在两个相机坐标系下的归一化坐标点(深度坐标化为1,只需给出相机内参 K K K和像素坐标即可得到

由式8可以得到:

s 2 K − 1 p 2 = s 1 R K − 1 p 1 + t (10) s_2\bm K^{-1}\bm p_2=s_1\bm{R\bm K^{-1}\bm p_1+t}\tag{10} s2K1p2=s1RK1p1+t(10)
两边同时左乘 t ∧ t ^\wedge t可得:
t ∧ s 2 ( K − 1 p 2 ) = t ∧ s 1 R ( K − 1 p 1 ) + 0 (11) t ^\wedge s_2\bm {(K^{-1}\bm p_2)}=t ^\wedge s_1\bm{R(\bm K^{-1}\bm p_1)+0}\tag{11} ts2(K1p2)=ts1R(K1p1)+0(11)
在左乘一个 ( K − 1 p 2 ) T \bm {(K^{-1}\bm p_2)}^T (K1p2)T,由叉乘的性质可得,向量 ( K − 1 p 2 ) \bm {(K^{-1}\bm p_2)} (K1p2) t ∧ ( K − 1 p 2 ) t ^\wedge \bm {(K^{-1}\bm p_2)} t(K1p2)正交(垂直),同时深度信息也消失了(失去了一个自由度)
0 = ( K − 1 p 2 ) T t ∧ s 1 R ( K − 1 p 1 ) (12) 0=\bm {(K^{-1}\bm p_2)}^Tt ^ \wedge \red {\sout {\textbf s_1}}\bm{R(\bm K ^{-1}\bm p_1)}\tag{12} 0=(K1p2)Tts1R(K1p1)(12)
由式12和式9可得:

x 2 T t ∧ R   x 1 = 0 \bm {x_2}^Tt ^\wedge \bm{R\space x_1}=0 x2TtR x1=0
其中, E = t ∧ R \bm E=t ^\wedge \bm R E=tR被称为本质矩阵,所以在本质矩阵中,包含了旋转和平移的信息。

接下来就是求解本质矩阵。
 
 

三、求解本质矩阵Rt

我们可以通过8个匹配点来求取本质矩阵 E \bm E E,这里继续介绍如何分解本质矩阵。

对本质矩阵进行SVD分解,首先对反对称矩阵 t ∧ t ^\wedge t分解:

t ∧ = κ ⋅ U Z U T = κ ⋅ U ⋅ d i a g ( 1 , 1 , 0 ) W T ⋅ U T   或 者 t ∧ = − κ ⋅ U ⋅ d i a g ( 1 , 1 , 0 ) W ⋅ U T     其 中 , W = [ 0 − 1 0 1 0 0 0 0 1 ] (13) t ^\wedge=\kappa \cdot \bm U\bm Z\bm U^T=\kappa \cdot \bm U\cdot diag(1,1,0)\bm W^T\cdot \bm U^T\\ ~\\或者\quad t ^\wedge=-\kappa \cdot \bm U\cdot diag(1,1,0)\bm W\cdot \bm U^T\\~\\ \\~\\ 其中,\bm W=\begin{bmatrix} 0 &-1&0\\ \\1&0&0\\\\0&0&1 \end{bmatrix} \tag{13} t=κUZUT=κUdiag(1,1,0)WTUT t=κUdiag(1,1,0)WUT  W=010100001(13)
所以本质矩阵有两种表示法:
E = t ∧ R = κ ⋅ U ⋅ d i a g ( 1 , 1 , 0 ) W T ⋅ U T R   E = t ∧ R = − κ ⋅ U ⋅ d i a g ( 1 , 1 , 0 ) W ⋅ U T R \bm E =t ^\wedge \bm R =\kappa \cdot \bm U\cdot diag(1,1,0)\bm W^T\cdot \bm U^T\bm R\\~\\ \bm E =t ^\wedge \bm R =-\kappa \cdot \bm U\cdot diag(1,1,0)\bm W\cdot \bm U^T\bm R E=tR=κUdiag(1,1,0)WTUTR E=tR=κUdiag(1,1,0)WUTR
对本质矩阵奇异值分解
E = U S 0 V T   则 V T = W ⋅ U T R 或 W T ⋅ U T R \bm E=\bm U\bm S_0 \bm V^T\\~\\则\quad \bm V^T=\bm W\cdot \bm U^T\bm R\quad或 \quad \bm W^T\cdot \bm U^T\bm R E=US0VT VT=WUTRWTUTR

由于 t ∧ t^ \wedge t特殊的特征值结构,所以可以推出本质矩阵奇异值一定是 d i a g ( σ , σ , 0 ) diag(\sigma,\sigma,0) diag(σ,σ,0)的形式,所以 κ \bm \kappa κ向量中的各元素相等,式13可以写成:

E = U ⋅ d i a g ( κ , κ , 0 ) ⋅ ( W ⋅ U T R ) (14) \bm E = \bm U\cdot diag(\kappa,\kappa,0)\cdot (\bm W\cdot \bm U^T\bm R)\tag{14} E=Udiag(κ,κ,0)(WUTR)(14)
分解得到 U 、 V \bm U、\bm V UV后,我们可以求出 R R R t t t

R = U W V T 或 R = U W T V T   t ∧ =   κ U ⋅ Z ⋅ U T 或 t ∧ = −   κ U ⋅ Z ⋅ U T     其 中 , Z = [ 0 1 0 − 1 0 0 0 0 0 ] , W = [ 0 − 1 0 1 0 0 0 0 1 ] \bm R= \bm U\bm W \bm V^T\quad或\quad \bm R= \bm U\bm W^T \bm V^T\\ ~\\\quad \bm t^ \wedge= \space\kappa\bm U\cdot \bm Z\cdot \bm U^T \quad 或 \quad \bm t^ \wedge= - \space\kappa\bm U\cdot \bm Z\cdot \bm U^T\\ ~\\~\\ 其中,\quad \bm Z=\begin{bmatrix} 0 &1&0\\ \\-1&0&0\\\\0&0&0 \end{bmatrix},\bm W=\begin{bmatrix} 0 &-1&0\\ \\1&0&0\\\\0&0&1 \end{bmatrix} R=UWVTR=UWTVT t= κUZUTt= κUZUT  Z=010100000,W=010100001
又由于其尺度的等价性,可以忽略掉常数 κ \kappa κ,所以我们通常又可以把平移矩阵记为:
t ∧ = ±   κ U ⋅ Z ⋅ U T \bm t^ \wedge= \pm \space \sout \red \kappa \bm U\cdot \bm Z\cdot \bm U^T t=± κUZUT

如图所示,我们解出的值有四种组合,这里就有了四种情况,但只有一种 R R R t t t使得相机的深度为正值

我们可以利用计算得到的值 R \bm R R t \bm t t,代入到 K ( R P w + t ) \bm{K(RP_w+t)} K(RPw+t)中进行验证,得到最优的解;


另外我们也可以利用OpenCV自带的函数进行求解,利用findEssentialMat函数进行求解:

Mat essential_matrix;
essential_matrix = findEssentialMat ( points1, points2, focal_length, principal_point, RANSAC );
recoverPose ( essential_matrix, points1, points2, R, t, focal_length, principal_point );

也可以通过基础矩阵求解:

Mat fundamental_matrix;
fundamental_matrix = findFundamentalMat ( points1, points2, CV_FM_8POINT );

至此,我们就可以估计相机的运动了.

 
 

四、三角测量

由式10可以得到:
s 2 K − 1 p 2 = s 1 R K − 1 p 1 + t (15) s_2\bm K^{-1}\bm p_2=s_1\bm{R\bm K^{-1}\bm p_1+t}\tag{15} s2K1p2=s1RK1p1+t(15)

s 2 x 2 = s 1 R x 1 + t (16) s_2\bm x_2=s_1\bm{R\bm x_1+t}\tag{16} s2x2=s1Rx1+t(16)
我们只要知道了s1,就能求出s2,一般来说,由于噪声的存在,我们用的是最小二乘解,而不是零解。我们可以利用cv::triangulatePoints函数来求解方程。

参考代码:

void triangulation ( 
    const vector< KeyPoint >& keypoint_1, 
    const vector< KeyPoint >& keypoint_2, 
    const std::vector< DMatch >& matches,
    const Mat& R, const Mat& t, 
    vector< Point3d >& points )
{
    Mat T1 = (Mat_<float> (3,4) <<
        1,0,0,0,
        0,1,0,0,
        0,0,1,0);
    Mat T2 = (Mat_<float> (3,4) <<
        R.at<double>(0,0), R.at<double>(0,1), R.at<double>(0,2), t.at<double>(0,0),
        R.at<double>(1,0), R.at<double>(1,1), R.at<double>(1,2), t.at<double>(1,0),
        R.at<double>(2,0), R.at<double>(2,1), R.at<double>(2,2), t.at<double>(2,0)
    );
    
    Mat K = ( Mat_<double> ( 3,3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );
    vector<Point2f> pts_1, pts_2;
    for ( DMatch m:matches )
    {
        // 将像素坐标转换至相机坐标
        pts_1.push_back ( pixel2cam( keypoint_1[m.queryIdx].pt, K) );
        pts_2.push_back ( pixel2cam( keypoint_2[m.trainIdx].pt, K) );
    }
    
    Mat pts_4d;
    cv::triangulatePoints( T1, T2, pts_1, pts_2, pts_4d );
    
    // 转换成非齐次坐标
    for ( int i=0; i<pts_4d.cols; i++ )
    {
        Mat x = pts_4d.col(i);
        x /= x.at<float>(3,0); // 归一化
        Point3d p (
            x.at<float>(0,0), 
            x.at<float>(1,0), 
            x.at<float>(2,0) 
        );
        points.push_back( p );
    }
}

参考文献

1.Multiple View Geometry in Computer Vision Second Edition. P258-259.
2.奇异值分解(SVD)
3.视觉SLAM十四讲—第7讲:视觉里程计
4.百度百科:实反对称矩阵

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值