利用ICP把自己跑出的数据与开源数据集对齐并显示(一.时间戳对齐)

 我们采集的数据集时间戳通常与给定的groundtruth的时间戳不对齐,下面以EuRoC数据集data.csv和我们采集的CameraTrajectory.txt为例介绍两者之间的对齐。

一.data.csv转ground.txt

    //改写成txt文件
    ifstream ifile("data.csv");
    string line,s;
    vector<vector<double>> timestamp;
    while(getline(ifile,line))
    {
        stringstream record(line);
        record>>s;
        if(s[0]=='#')//跳过注释
            continue;
        vector<double> time;
        double ti;
        string str;
        for(auto &s:line)//把每一行的逗号都替换成空格
            if(s==',')
                s=' ';
        stringstream rd(line);
        for(auto i=0;i<8;i++)
        {
            rd>>ti;
            if(i==0)
            {
                setprecision(8);//使得时间戳与自己数据时间戳格式一致
                ti=ti/(10e8);
            }
            time.push_back(ti);
        }
        timestamp.push_back(time);
        record.clear();
    }
    ifile.close();
    ofstream ofile("../ground.txt");
    for(auto time:timestamp) {
        for (auto ti:time)
            ofile <<fixed<< ti << " ";
        ofile<<endl;
    }
    ofile.close();

二.对齐ground.txt与CameraTrajectory.txt

    ifstream fileGround("../ground.txt");
    ifstream fileEstimated("../CameraTrajectory.txt");
    string lineNew;
    vector<vector<double>> vTraGround,vTraEstimated,vTraGroundAligned,vTraEstimatedAligned;
    while(getline(fileGround,lineNew))//读取ground并保存成矩阵
    {
        stringstream record(lineNew);
        vector<double> vTmpGround;
        double tmp;
        for(auto i=0;i<8;i++)
        {
            record>>tmp;
            vTmpGround.push_back(tmp) ;
        }
        vTraGround.push_back(vTmpGround);
        record.clear();
    }
    while(getline(fileEstimated,lineNew))//读取CaneraTrajectory并保存成矩阵
    {
        stringstream record(lineNew);
        vector<double> vTmpEstimated;
        double tmp;
        for(auto i=0;i<8;i++)
        {
            record>>tmp;
            vTmpEstimated.push_back(tmp);
        }
        vTraEstimated.push_back(vTmpEstimated);
        record.clear();
    }
    auto it = vTraGround.begin();
    for(auto tmpEst:vTraEstimated)//对齐时间戳
    {
        double timeStampEst = tmpEst[0];
        for (; it != vTraGround.end(); it++)
        {
            double timeStampGrd = (*it)[0];
            if(abs(timeStampGrd-timeStampEst)<=0.0004)//允许一定的容差
            {
                vTraGroundAligned.push_back(*it);
                vTraEstimatedAligned.push_back(tmpEst);
            }
            else if(timeStampGrd < timeStampEst)
                continue;
            else if(timeStampGrd > timeStampEst)
                break;
        }
    }
    ofstream ofileGrd("../GroundAligned.txt");//写入对齐后的ground数据
    for(auto vTra:vTraGroundAligned) {
        for (auto ele:vTra)
            ofileGrd << fixed << ele << " ";
        ofileGrd << endl;
    }
    ofstream ofileEst("../EstimatedAligned.txt");//写入对齐后的CameraTrajectory数据
    for(auto vTra:vTraEstimatedAligned) {
        for (auto ele:vTra)
            ofileEst << fixed << ele << " ";
        ofileEst << endl;
    }
    return 0;

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用 ORBSLAM3 TUM 数据集并输对齐后轨迹文件的 C++ 代码示例: ```c++ #include <iostream> #include <fstream> #include <sstream> #include <string> #include <iomanip> #include <opencv2/core/core.hpp> #include "System.h" using namespace std; int main(int argc, char **argv) { if(argc != 4) { cerr << endl << "Usage: ./mono_tum path_to_vocabulary path_to_settings path_to_dataset" << endl; return 1; } ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::MONOCULAR,true); ifstream fGroundTruth; fGroundTruth.open(argv[3] + string("/groundtruth.txt")); if(!fGroundTruth.is_open()) { cerr << endl << "Failed to open file: " << argv[3] + string("/groundtruth.txt") << endl; return 1; } ofstream fTrajectory; fTrajectory.open("trajectory.txt"); if(!fTrajectory.is_open()) { cerr << endl << "Failed to open file: trajectory.txt" << endl; return 1; } string sLine; int nLineNum = 0; while(getline(fGroundTruth,sLine)) { if(sLine.empty() || sLine[0] == '#') continue; nLineNum++; double t; float tx, ty, tz, qx, qy, qz, qw; stringstream ss; ss << sLine; ss >> t >> tx >> ty >> tz >> qx >> qy >> qz >> qw; cv::Mat Tcw = SLAM.TrackMonocular(cv::Mat(),cv::Mat(),t); if(!Tcw.empty()) { cv::Mat Rwc = Tcw.rowRange(0,3).colRange(0,3).t(); cv::Mat twc = -Rwc*Tcw.rowRange(0,3).col(3); float x = twc.at<float>(0); float y = twc.at<float>(1); float z = twc.at<float>(2); float roll, pitch, yaw; ORB_SLAM3::Converter::QuaternionToEuler(qw,qx,qy,qz,roll,pitch,yaw); float scale = 1.0f; if(nLineNum > 1) { getline(fGroundTruth,sLine); double tPrev; float txPrev, tyPrev, tzPrev, qxPrev, qyPrev, qzPrev, qwPrev; stringstream ssPrev; ssPrev << sLine; ssPrev >> tPrev >> txPrev >> tyPrev >> tzPrev >> qxPrev >> qyPrev >> qzPrev >> qwPrev; cv::Mat Twc = cv::Mat::eye(4,4,CV_32F); ORB_SLAM3::Converter::QuaternionToMat(qxPrev,qyPrev,qzPrev,qwPrev,Twc.rowRange(0,3).colRange(0,3)); Twc.at<float>(0,3) = txPrev; Twc.at<float>(1,3) = tyPrev; Twc.at<float>(2,3) = tzPrev; cv::Mat Ow = Twc.rowRange(0,3).col(3); cv::Mat OwPrev = cv::Mat(3,1,CV_32F); OwPrev.at<float>(0) = txPrev; OwPrev.at<float>(1) = tyPrev; OwPrev.at<float>(2) = tzPrev; cv::Mat v = Ow - OwPrev; scale = cv::norm(v); } fTrajectory << fixed << setprecision(6) << t << " " << x << " " << y << " " << z << " " << roll << " " << pitch << " " << yaw << " " << scale << endl; } } fGroundTruth.close(); fTrajectory.close(); SLAM.Shutdown(); return 0; } ``` 注意事项: 1. 代码中的 `path_to_vocabulary` 和 `path_to_settings` 分别表示 ORB_SLAM3 的词汇文件和配置文件路径,需要根据实际情况进行修改。 2. 代码中的 `path_to_dataset` 表示 TUM 数据集所在的文件夹路径,需要根据实际情况进行修改。 3. 输对齐轨迹文件为 `trajectory.txt`,每行数据包括时间戳、位置坐标、欧拉角和尺度因子,用空格分隔。 4. 代码中使用了 Ground Truth 数据进行轨迹对齐,需要保证 TUM 数据集中的 `groundtruth.txt` 文件是存在并且格式正确的。如果没有 Ground Truth 数据,可以使用其它方法进行轨迹对齐。 希望对你有帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值