ORB-SLAM代码详解之代码框架
2017-02-08 21:31
741 查看
工具篇
ORB-SLAM的代码框架
转载请注明出处:http://blog.csdn.net/c602273091/article/details/54933404
在这里我主要分析的是单目SLAM中的kitti数据集的流程图。
接下来从main函数开始抽丝剥茧:
整个main函数看下来,真正有价值的地方在于:
SLAM系统初始化:ORB_SLAM2::System
SLAM(argv[1],argv[2],ORB_SLAM2::System::MONOCULAR,true);
SLAM系统的追踪部分:SLAM.TrackMonocular(im,tframe);
次要的地方是
线程关闭:SLAM.Shutdown();
保存整条轨迹: SLAM.SaveKeyFrameTrajectoryTUM(“KeyFrameTrajectory.txt”); 看了源码我觉得如果是kitti的数据集的话,应该调用SaveTrajectoryKITTI
当然在看代码之前把ORB-SLAM的论文看一遍非常重要。对于这片论文的介绍,可以看我的系列文章【2】【3】【4】。
参考链接:
【1】understand下载: http://www.qqtn.com/down/91669.html
【2】http://blog.csdn.net/c602273091/article/details/54348202
【3】http://blog.csdn.net/c602273091/article/details/54411989
【4】http://blog.csdn.net/c602273091/article/details/54428693
ORB-SLAM的代码框架
转载请注明出处:http://blog.csdn.net/c602273091/article/details/54933404
工具篇
在看代码方面,有不少软件推荐。我觉得首推还是得Understand【1】,这个工具可以把代码的流程图、依赖关系、整个框架给描述出来。有钱的话,买正版。其次的话,我推荐SourceInsight。这个工具比较方便看出你的类的定义。我在使用的时候一般是上面一半是代码,下面一半看类的定义。这样看代码就是事半功倍。ORB-SLAM的代码框架
在这里我主要分析的是单目SLAM中的kitti数据集的流程图。
接下来从main函数开始抽丝剥茧:
/** * This file is part of ORB-SLAM2. * * Copyright (C) 2014-2016 Ra煤l Mur-Artal <raulmur at unizar dot es> (University of Zaragoza) * For more information see <https://github.com/raulmur/ORB_SLAM2> * * ORB-SLAM2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ORB-SLAM2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ORB-SLAM2. If not, see <http://www.gnu.org/licenses/>. */ #include<iostream> #include<algorithm> #include<fstream> #include<chrono> #include<iomanip> #include<opencv2/core/core.hpp> #include"System.h" using namespace std; // 从文件夹中load图片进来 void LoadImages(const string &strSequence, vector<string> &vstrImageFilenames, vector<double> &vTimestamps); int main(int argc, char **argv) { // 判断参数是否符合规范 // ./mono_kitti path_to_vocabulary path_to_settings path_to_sequence // 一共有四个参数:可执行文件argv[0]、字典的目录argv[1]、配置的路径argv[2]、图片序列的路径argv[3] if(argc != 4) { cerr << endl << "Usage: ./mono_kitti path_to_vocabulary path_to_settings path_to_sequence" << endl; return 1; } // Retrieve paths to images vector<string> vstrImageFilenames; vector<double> vTimestamps; // 加载图片,传入图片路径、传回的是图片的文件名、每幅图片的时间戳 LoadImages(string(argv[3]), vstrImageFilenames, vTimestamps); // 图片的个数 int nImages = vstrImageFilenames.size(); // 对SLAM系统进行初始化,传入字典和配置的路径 // Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM2::System SLAM(argv[1],argv[2],ORB_SLAM2::System::MONOCULAR,true); // Vector for tracking time statistics vector<float> vTimesTrack; // 计算追踪所花的时间 vTimesTrack.resize(nImages); cout << endl << "-------" << endl; cout << "Start processing sequence ..." << endl; cout << "Images in the sequence: " << nImages << endl << endl; // Main loop cv::Mat im; for(int ni=0; ni<nImages; ni++) { // Read image from file im = cv::imread(vstrImageFilenames[ni],CV_LOAD_IMAGE_UNCHANGED); double tframe = vTimestamps[ni]; if(im.empty()) { cerr << endl << "Failed to load image at: " << vstrImageFilenames[ni] << endl; return 1; } #ifdef COMPILEDWITHC11 // 如果编译器可以编译c++11 // 获取当前时间 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); #else std::chrono::monotonic_clock::time_point t1 = std::chrono::monotonic_clock::now(); #endif // Pass the image to the SLAM system // 图片放入SLAM系统中进行追踪 SLAM.TrackMonocular(im,tframe); #ifdef COMPILEDWITHC11 std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); #else std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now(); #endif double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count(); // 计算追踪该图片花的时间 vTimesTrack[ni]=ttrack; // Wait to load the next frame // 计算下一帧图片时间戳与当前时间戳的差值T,与追踪所需时间进行比较 // 如果有必要就将当前线程暂停sleep // 主要是为了模拟时间情况,因为追踪结束以后下一帧可能还没来 double T=0; if(ni<nImages-1) T = vTimestamps[ni+1]-tframe; else if(ni>0) T = tframe-vTimestamps[ni-1]; if(ttrack<T) usleep((T-ttrack)*1e6); } // Stop all threads // 追踪完所有图片序列以后,关掉当前的线程 SLAM.Shutdown(); // Tracking time statistics // 对追踪的部分进行一个统计 // 计算中位数,总数、平均值 sort(vTimesTrack.begin(),vTimesTrack.end()); float totaltime = 0; for(int ni=0; ni<nImages; ni++) { totaltime+=vTimesTrack[ni]; } cout << "-------" << endl << endl; cout << "median tracking time: " << vTimesTrack[nImages/2] << endl; cout << "mean tracking time: " << totaltime/nImages << endl; // Save camera trajectory // 保存整个相机的位姿的轨迹 SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt"); return 0; } void LoadImages(const string &strPathToSequence, vector<string> &vstrImageFilenames, vector<double> &vTimestamps) { ifstream fTimes; // 读4541幅图片的时间戳(kitti的00图片序列) string strPathTimeFile = strPathToSequence + "/times.txt"; // string类型转化为char*类型 fTimes.open(strPathTimeFile.c_str()); while(!fTimes.eof()) { string s; getline(fTimes,s); if(!s.empty()) { // string类型转化为double类型 // 使用stringstream类型 stringstream ss; ss << s; double t; ss >> t; vTimestamps.push_back(t); } } // 使用image_0目录下的文件,这是双目摄像头的左边的摄像头的序列 string strPrefixLeft = strPathToSequence + "/image_0/"; const int nTimes = vTimestamps.size(); vstrImageFilenames.resize(nTimes); for(int i=0; i<nTimes; i++) { stringstream ss; // 设置0~nTime-1的图片的路径 ss << setfill('0') << setw(6) << i; vstrImageFilenames[i] = strPrefixLeft + ss.str() + ".png"; } }
整个main函数看下来,真正有价值的地方在于:
SLAM系统初始化:ORB_SLAM2::System
SLAM(argv[1],argv[2],ORB_SLAM2::System::MONOCULAR,true);
SLAM系统的追踪部分:SLAM.TrackMonocular(im,tframe);
次要的地方是
线程关闭:SLAM.Shutdown();
保存整条轨迹: SLAM.SaveKeyFrameTrajectoryTUM(“KeyFrameTrajectory.txt”); 看了源码我觉得如果是kitti的数据集的话,应该调用SaveTrajectoryKITTI
当然在看代码之前把ORB-SLAM的论文看一遍非常重要。对于这片论文的介绍,可以看我的系列文章【2】【3】【4】。
参考链接:
【1】understand下载: http://www.qqtn.com/down/91669.html
【2】http://blog.csdn.net/c602273091/article/details/54348202
【3】http://blog.csdn.net/c602273091/article/details/54411989
【4】http://blog.csdn.net/c602273091/article/details/54428693
相关文章推荐
- ORB-SLAM2详解1 框架说明
- SLAM入门之ORBSLAM2代码理解——系统框架
- ORB-SLAM2详解(二)代码逻辑
- ORB-Slam详解2 代码流程
- ORB-SLAM代码详解之SLAM.TrackMonocular
- ORB-SLAM2详解(二)代码逻辑
- ORB-SLAM代码详解之SLAM系统初始化
- ORB-SLAM2详解(一)简介
- ORB-SLAM2详解(三)自动地图初始化
- 详解CSS的Sass框架中代码注释的编写方法
- ROS SLAM代码框架概述
- Spring整合JUnit框架进行单元测试代码使用详解
- AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
- Spring整合JUnit框架进行单元测试代码使用详解
- ORB-SLAM2源码详解
- ORB-SLAM2详解(四)跟踪
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- Android开发之常用框架WebView详解代码。超详细,送给初学者,完全掌握此控件