能跑kitti数据集的单目视觉里程计有哪些?

能跑kitti数据集的单目视觉里程计有哪些?比如ORB-SLAM
最好带有回环检测的
开源能用的

以下
ORB-SLAM2
SVO
DSO
PTAM
LDSO
VISO2
OKVIS
ROVIO
MSCKF
SLAM++

  • 你可以参考下这篇文章:ORB-SLAM2编译安装以及跑KITTI数据集
  • 除此之外, 这篇博客: 零基础学习ORB-SLAM2特征点提取-从原理到源码【李哈哈】中的 mono_kitti.cc 1.0 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 我们采用mono_kitti.cc来开始程序,也就是针对单目kitti数据集来研究。
    进入main函数,定义了两个容器来存放每张图片的路径和时间戳:

    // Retrieve paths to images
    vector<string> vstrImageFilenames; //图像序列中每张图片存放路径
    vector<double> vTimestamps;        //图像序列中每张图片时间戳
    

    然后执行LoadImages函数:

    //!这是一个非常关键的读文件函数
    //argv[3]存放的是图像序列的存放路径,是从外界输入的路径
    LoadImages(string(argv[3]), vstrImageFilenames, vTimestamps);
    

    该函数也在mono_kitti.cc文件中,函数定义如下:

    //以下为LoadImages函数定义,这是该文件夹唯一的函数
    // 函数定义:获取图像序列中每一张图像的访问路径和时间戳
    void LoadImages(const string &strPathToSequence, vector<string> &vstrImageFilenames, vector<double> &vTimestamps)
    {
        // step 1 读取时间戳文件
        ifstream fTimes; //定义一个输入流fTimes来读取文件中的时间戳(ifstream用来读取)
        //调用数据集中的时间戳文件
        string strPathTimeFile = strPathToSequence + "/times.txt"; //strPathTimeFile是一个路径,末位追踪到time.txt
    
        //c_str是string类的一个函数,可以把string类型变量转换成char*变量
        //open()要求的是一个char*字符串
        //当文件名是string时需要转换,当文件名是字符数组型时就不需要此转换
        fTimes.open(strPathTimeFile.c_str()); //使用输入流读取文件,调用了open()函数
        while (!fTimes.eof())                 //.eof()函数判断文件夹是否读到最后
        {
            string s;
            getline(fTimes, s); //自动读取下一行时间戳文件
            // 如果该行字符串不是空的,就写进流,读成double类型放入vector(用来改变数据类型)
            if (!s.empty())
            {
                //流对象,用于流的输入输出
                stringstream ss;
                ss << s;
                double t;
                ss >> t;
                // 保存时间戳
                vTimestamps.push_back(t);
                //!至此,vTimestamps储存了所有的时间戳
            }
        }
    
        // step 1 使用左目图像, 生成左目图像序列中的每一张图像的文件名
        //组装mono_kitti数据集中image_0目录的路径
        string strPrefixLeft = strPathToSequence + "/image_0/";
    
        const int nTimes = vTimestamps.size(); //有多少个时间戳
        vstrImageFilenames.resize(nTimes);     //重定义有多少个时间戳就有多少个图像,保持维度的一致性,但是之前也没规定有多少少图像
    
        for (int i = 0; i < nTimes; i++)
        {
            stringstream ss;
            //std::setw :需要填充多少个字符,默认填充的字符为' '空格
            //std::setfill:设置std::setw将填充什么样的字符,如:std::setfill('*')
            //ss总共为6位,i之外的前边几位用0来填充,得到的结果为000001 000099之类
            ss << setfill('0') << setw(6) << i; //填6个0,如果来了个i,则代替0的位置,也就是总共有6位,末尾是i,其他用0填充
            vstrImageFilenames[i] = strPrefixLeft + ss.str() + ".png";
            //!至此,组装形成包含图像路径和编号的vector
        }
    }
    

    执行完该函数后,成功将每张图片的路径及时间戳读取到刚刚定义的两个vector容器中
    main函数继续执行,定义了变量nImages来存储有多少个图片:

    int nImages = vstrImageFilenames.size(); //有nImages个图片
    

    main函数继续执行,实例化一个SLAM对象:

    //!实例化SLAM对象
    // Create SLAM system. It initializes all system threads and gets ready to process frames.
    //argv1是词袋地址,argv2是配置文件的地址,第三个参数是传感器类型,第四个参数为是否选择使用可视化界面
    //argv[1]为vocfile 里边存储的是词汇
    //argv[2]为settingfile 里边存储摄像机校准和畸变参数和ORB相关参数
    //这里创建了System类型的SLAM对象,SLAM构造函数中初始化了系统所有线程和相关参数,并准备好处理帧,代码留待后边详细分析
    //读入词包路径,读入YAML配置文件,设置SLAM为mono状态,启用viewer的线程简要说明
    ORB_SLAM2::System SLAM(argv[1], argv[2], ORB_SLAM2::System::MONOCULAR, true);
    

    这里说是实例化SLAM对象,其实是指创建了一个System类的对象,并取名为SLAM,该类的定义在System.cc文件