从零手写vio-作业6-三角化

在这里插入图片描述

2完成三角化代码

源码如下:

//
// Created by nnz on 18-11-11.
//
#include <iostream>
#include <vector>
#include <random>  
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/Eigenvalues>
using namespace std;
//
struct Pose
{
    
    
    Pose(Eigen::Matrix3d R, Eigen::Vector3d t):Rwc(R),qwc(R),twc(t) {
    
    };
    Eigen::Matrix3d Rwc;
    Eigen::Quaterniond qwc;
    Eigen::Vector3d twc;

    Eigen::Vector2d uv;    // 这帧图像观测到的特征坐标
};
int main()
{
    
    

    int poseNums = 10;
    double radius = 8;//半径
    double fx = 1.;
    double fy = 1.;
    std::vector<Pose> camera_pose;//
    for(int n = 0; n < poseNums; ++n )//生成的
    {
    
    
        double theta = n * 2 * M_PI / ( poseNums * 4); // 1/4 圆弧
        // 绕 z轴 旋转
        Eigen::Matrix3d R;
        R = Eigen::AngleAxisd(theta, Eigen::Vector3d::UnitZ());
        Eigen::Vector3d t = Eigen::Vector3d(radius * cos(theta) - radius, radius * sin(theta), 1 * sin(2 * theta));
        camera_pose.push_back(Pose(R,t));
    }

    // 随机数生成 1 个 三维特征点
    std::default_random_engine generator;
    std::uniform_real_distribution<double> xy_rand(-4, 4.0);
    std::uniform_real_distribution<double> z_rand(8., 10.);
    double tx = xy_rand(generator);
    double ty = xy_rand(generator);
    double tz = z_rand(generator);

    Eigen::Vector3d Pw(tx, ty, tz);
    // 这个特征从第三帧相机开始被观测,i=3
    int start_frame_id = 3;
    int end_frame_id = poseNums;
    for (int i = start_frame_id; i < end_frame_id; ++i) {
    
    
        Eigen::Matrix3d Rcw = camera_pose[i].Rwc.transpose();
        Eigen::Vector3d Pc = Rcw * (Pw - camera_pose[i].twc);

        double x = Pc.x();
        double y = Pc.y();
        double z = Pc.z();

        camera_pose[i].uv = Eigen::Vector2d(x/z,y/z);
    }
    
    /// TODO::homework; 请完成三角化估计深度的代码
    // 遍历所有的观测数据,并三角化
    Eigen::Vector3d P_est;           // 结果保存到这个变量
    P_est.setZero();
    /* your code begin */



    // step 1 construct D
    int D_rows=2*(end_frame_id-start_frame_id);//D的行数
    Eigen::MatrixXd D=Eigen::MatrixXd::Zero(D_rows,4);//初始化一下D
    for(int i=start_frame_id;i<end_frame_id;++i)
    {
    
    
        Eigen::Matrix<double,3,4> Tcw;
        Eigen::Matrix3d Rcw=camera_pose[i].Rwc.transpose();
        Eigen::Vector3d tcw=-Rcw*camera_pose[i].twc;
        Tcw<<Rcw,tcw;
        D.block(2*(i-start_frame_id),0,1,4)=camera_pose[i].uv(0)*Tcw.row(2)
                                                                                    -Tcw.row(0);
        D.block(2*(i-start_frame_id)+1,0,1,4)=camera_pose[i].uv(1)*Tcw.row(2)
                                                                                      -Tcw.row(1);
    }
    //step 2 放缩 max取D的最大的元素
    double max=D.maxCoeff();
    cout<<"D = "<< endl<<D <<endl;
    cout<<"The max num of D ="<< max <<endl;
    Eigen::MatrixXd DTD=(D/max).transpose()*(D/max);

    clock_t time_stt = clock();

   Eigen::JacobiSVD<Eigen::MatrixXd> svd_h(DTD,Eigen::ComputeThinU | Eigen::ComputeThinV);

    clock_t time_stt1 = clock();
    std::cout<<"SVD分解,耗时:\n"<<(clock()-time_stt1)/(double) CLOCKS_PER_SEC<<"ms"<<std::endl;

    Eigen::MatrixXd U=svd_h.matrixU();
    Eigen::MatrixXd V=svd_h.matrixV();
    Eigen::MatrixXd S(svd_h.singularValues());
    cout<<"U = "<<endl<<U<<endl;
    cout<<"V = "<<endl<<V<<endl;
    cout<<" singularValues "<< endl<<S <<endl;

    //step 3 判断是否有效

    if(abs(svd_h.singularValues()[3]/svd_h.singularValues()[2])<1e-2)
    {
    
    
        Eigen::Vector4d u4=max*U.block(0,3,4,1);
        P_est=(u4/u4[3]).head(3);//归一化
    }
    else
    {
    
    
        cout<<"无效!"<<endl;
    }
    /* your code end */
    
    std::cout <<"ground truth: \n"<< Pw.transpose() <<std::endl;
    std::cout <<"your result: \n"<< P_est.transpose() <<std::endl;
    return 0;
}

运行结果如下:

D = 
-0.891007  -0.45399 -0.478253   1.25886
  0.45399 -0.891007 -0.339294   3.90642
-0.809017 -0.587785 -0.548566   2.04958
 0.587785 -0.809017 -0.432396   5.11352
-0.707107 -0.707107 -0.626707   2.96985
 0.707107 -0.707107  -0.51176   6.16861
-0.587785 -0.809017 -0.707633   3.97072
 0.809017 -0.587785 -0.571913   7.01606
 -0.45399 -0.891007  -0.78662   5.00446
 0.891007  -0.45399 -0.609762   7.62136
-0.309017 -0.951057 -0.860286   6.03353
 0.951057 -0.309017 -0.625116   7.97589
-0.156434 -0.987688 -0.927108   7.03502
 0.987688 -0.156434 -0.620237   8.09317
The max num of D =8.09317
SVD分解,耗时:
1e-06ms
U = 
0.0530721  0.846878   0.41558  0.327528
-0.103079  0.431629 -0.895388 0.0367562
-0.102585  0.309021  0.122288 -0.937565
 0.987945 0.0316285 -0.103049 -0.111113
V = 
0.0530721  0.846878   0.41558  0.327528
-0.103079  0.431629 -0.895388 0.0367562
-0.102585  0.309021  0.122288 -0.937565
 0.987945 0.0316285 -0.103049 -0.111113
 singularValues 
     7.1513
   0.118267
  0.0110422
1.88518e-17
ground truth: 
  -2.9477 -0.330799   8.43792
your result: 
  -2.9477 -0.330799   8.43792

猜你喜欢

转载自blog.csdn.net/joun772/article/details/110876326