深蓝学院《从零开始手写VIO》作业六

深蓝学院《从零开始手写VIO》作业五

  • 深蓝学院《从零开始手写VIO》作业六
    • 1. 证明题
    • 2. 代码题

深蓝学院《从零开始手写VIO》作业六

1. 证明题

证明 D y = 0 Dy=0 Dy=0的最优解 y y y等于 D T D D^TD DTD的最小奇异值对应的奇异值向量

矩阵 D T D D^TD DTD的奇异值分解如下:
D ⊤ D = ∑ i = 1 4 σ i 2 u i u j ⊤ \mathbf{D}^{\top} \mathbf{D}=\sum_{i=1}^{4} \sigma_{i}^{2} \mathbf{u}_{i} \mathbf{u}_{j}^{\top} DD=i=14σi2uiuj
回顾我们的原始问题如下:
求解 D 2 n × 4 y 4 × 1 = 0 D_{2n×4}y_{4×1}=0 D2n×4y4×1=0,这是一个超定方程,本质上求解得到的是一个最小二乘解,使用如下表示:
min ⁡ y ∣ ∣ D y ∣ ∣ 2 = ( D y ) T ( D y ) = y T D T D y \min _{y} ||Dy||^2 = (Dy)^T(Dy) = y^TD^TDy yminDy2=(Dy)T(Dy)=yTDTDy
其中 ∣ ∣ y ∣ ∣ = 1 ||y|| = 1 y=1

y y y可以由 D T D D^TD DTD的奇异值向量线性组合得到,也就是可以表示成如下形式
y = ∑ i = 1 4 k i u i = k i u i + v y = \sum_{i=1}^{4} k_iu_i = k_iu_i+v y=i=14kiui=kiui+v
其中 v = ∑ j = 1 , j ≠ i 4 k j u j v=\sum_{j=1,j\not=i}^{4}k_ju_j v=j=1,j=i4kjuj
k i , k j ∈ R k_i,k_j \in R ki,kjR
容易知道 u i u_i ui v v v正交。
y y y代入 y T D T D y y^TD^TDy yTDTDy得到
min ⁡ y ∣ ∣ D y ∣ ∣ 2 = ( k i u i + v ) T D T D ( k i u i + v ) = k i 2 u i T D T D u i + v T D T D v + k i u i T D T D v + k i v T D T D u i \min _{y} ||Dy||^2 = (k_iu_i+v)^TD^TD(k_iu_i+v) = k_i^2u_i^TD^TDu_i+ v^TD^TDv + k_iu_i^TD^TDv +k_iv^TD^TDu_i yminDy2=(kiui+v)TDTD(kiui+v)=ki2uiTDTDui+vTDTDv+kiuiTDTDv+kivTDTDui

由于 u i u_i ui v v v正交,所以后两项为0;并且 D u i = σ i u i Du_i = \sigma_iu_i Dui=σiui,带入得到
min ⁡ y ∣ ∣ D y ∣ ∣ 2 = ( k i u i + v ) T D T D ( k i u i + v ) = k i 2 u i T D T D u i + v T D T D v = k i 2 σ i 2 ∣ ∣ u i ∣ ∣ 2 + v T D T D v > = k i 2 σ i 2 ∣ ∣ u i ∣ ∣ 2 \min _{y} ||Dy||^2 = (k_iu_i+v)^TD^TD(k_iu_i+v) = k_i^2u_i^TD^TDu_i+ v^TD^TDv = k_i^2\sigma_i^2||u_i||^2 + v^TD^TDv >= k_i^2\sigma_i^2||u_i||^2 yminDy2=(kiui+v)TDTD(kiui+v)=ki2uiTDTDui+vTDTDv=ki2σi2ui2+vTDTDv>=ki2σi2ui2
当且仅当 v = 0 v=0 v=0的时候等号成立。
如果想取得最小值,则 σ i = σ 4 \sigma_i=\sigma_4 σi=σ4,也就是取得最小奇异值的时候,目标函数取得最小值,此时
y = k 4 u 4 + v = k 4 u 4 y = k_4u_4+v=k_4u_4 y=k4u4+v=k4u4
由于 ∣ ∣ y ∣ ∣ = 1 ||y||=1 y=1,所以 k 4 = 1 k_4=1 k4=1,所以
y = u 4 y = u_4 y=u4
证明完毕。

2. 代码题

代码如下:

    /// TODO::homework; 请完成三角化估计深度的代码
    // 遍历所有的观测数据,并三角化
    Eigen::Vector3d P_est;           // 结果保存到这个变量
    P_est.setZero();
    /* your code begin */
    Eigen::MatrixXd matD = ConstructMatrixD(camera_pose);
    Eigen::BDCSVD bcdsvd(matD.transpose()*matD, Eigen::ComputeFullV | Eigen::ComputeFullU);
    auto singular_values = bcdsvd.singularValues();
    auto matU = bcdsvd.matrixU();
    auto matV = bcdsvd.matrixV();


    // result 1
    auto tmp_y = matU.rightCols(1);
    auto real_y = tmp_y/tmp_y(3);

    // result2
    double s = matD.maxCoeff();
    Eigen::Matrix4d scale_mat = Eigen::Matrix4d::Identity()/s;
    auto matD_new = matD*scale_mat;
    Eigen::BDCSVD bcdsvd_new(matD_new.transpose()*matD_new, Eigen::ComputeFullV | Eigen::ComputeFullU);
    auto matU_new = bcdsvd_new.matrixU();
    auto tmp_y_new = scale_mat*matU_new.rightCols(1); //结果一样
    auto real_y_new = tmp_y_new/tmp_y_new(3);
    /* your code end */

结果如下:

ground truth: 
  -2.9477 -0.330799   8.43792
[normal solve] your result1: 
  -2.9477 -0.330799   8.43792         1
[using Scale solve] your result2: 
  -2.9477 -0.330799   8.43792         1

你可能感兴趣的:(视觉SLAM)