ORB-SLAM2编译安装以及跑KITTI数据集

ORB-SLAM2

http://webdiis.unizar.es/~raulmur/orbslam/

ORB-SLAM2是用于单目,双目和RGB-D相机的实时SLAM库,可计算相机轨迹和稀疏的3D重建(在具有真实比例的双目和RGB-D情况下)。 它能够实时检测环路并重新定位摄像机。 我们提供了一些示例,以在KITTI数据集以双目或单目,在TUM数据集以RGB-D或单眼,在EuRoC数据集以双目或单眼运行SLAM系统。 我们还提供了一个ROS节点来处理实时单眼,双目或RGB-D流。 该库可以在没有ROS的情况下进行编译。 ORB-SLAM2提供了一个可在SLAM模式和本地化模式之间切换的GUI。

Clone the repository:

git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2

我们提供了一个脚本build.sh来构建第三方库和ORB-SLAM2。 请确保已安装所有必需的依赖项(C++11 or C++0x Compiler,Pangolin,OpenCV,Eigen3,DBoW2 and g2o ,ROS (optional) )。
如果依赖没有安装完整,会出现如下错误:
ORB-SLAM2编译安装以及跑KITTI数据集_第1张图片安装Pangolin

git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build
cd build
cmake ..
make 
sudo make install 

出现错误

CMake Error at CMakeModules/FindGLEW.cmake:51 (MESSAGE):
  Could not find GLEW

没有安装GLEW,利用apt-get进行安装

sudo apt-get install libglew-dev 

重新编译Pangolin,成功。
然后按照提供的官网教程编译ORB_SLAM2

cd ORB_SLAM2
chmod +x build.sh  //chmod +x的意思就是给执行权限
./build.sh

这将在lib文件夹中创建libORB_SLAM2.so,并在Examples文件夹中创建可执行文件mono_tum,mono_kitti,rgbd_tum,stereo_kitti,mono_euroc和stereo_euroc。

ORB_SLAM2 ROS运行KITTI数据集

1.下载KITTI-grayscale数据集
2.编译安装ROS版本的ORB-SLAM2

  • 使用ROS创建workspace
mkdir -p ~/catkin_orb_slam2_ws/src
cd ~/catkin_orb_slam2_ws/
catkin_make
mkdir ORB_SLAM2

将下载编译好的代码放到工作空间中,或者直接下载到工作空间中。

  • 添加环境变量:
echo "source ~/catkin_orb_slam2_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
  • 运行build.sh
sudo gedit ~/.bashrc
  • 修改环境变量(user就是用户的名字,把它改成你自己的路径名字,ORB-SLAM2/Examples/ROS所在的完整路径。)
export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/(user)/catkin_orb_slam2_ws/ORB_SLAM2/Examples/ROS
  • 编译安装ROS版本的ORB-SLAM2
cd ORB_SLAM2
chmod +x build_ros.sh
./build_ros.sh
  • 注意坑2:如果在编译构建的过程中出现关于boost库的错误,要到/Examples/ROS/ORB-SLAM2/CMakeLists.txt文件下修改 加上 -lboost_system
set(LIBS
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/../../../Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/../../../Thirdparty/g2o/lib/libg2o.so
${PROJECT_SOURCE_DIR}/../../../lib/libORB_SLAM2.so
#加上这一句
-lboost_system
)

3.mono_kitti单目数据集运行:
执行命令:ORB-SLAM2支持单目、双目和RGBD数据,这里选择mono_kitti的单目数据集来运行和调试。
运行命令格式为:

./mono_kitti path_to_vocabulary path_to_settings path_to_sequence

该命令共有4个参数:
mono_kitti:为ORB-SLAM2编译生成的针对MONO_KITTI数据集的可执行文件,一般路径为ORB-SLAM2工程目录下Examples/Monocular/mono_kitti

path_to_vocabulary为所选词典的路径,路径为ORB_SLAM2/Vocabulary/ORBvoc.txt;

path_to_settings为配置文件,存放在ORB-SLAM2/Examples/Monocular下,运行时选择了KITTI00-02.yaml(可选择别的),该配置文件中存放的相机的内参和外参,提取特征时候图像金字塔相关参数,可视化过程中用到的参数;

path_to_sequence为数据集路径,这个根据自己下载的kitti数据集路径来指定。这里在工作空间中建立文件夹dataset来存放数据集00,故目录为 …/dataset/sequences/00/ (…/表示上层目录,./表示当前目录)
在ORB_SLAM2文件夹下打开终端,执行以下命令来运行程序:

./Examples/Monocular/mono_kitti Vocabulary/ORBvoc.txt Examples/Monocular/KITTI00-02.yaml ../dataset/sequences/00/

运行之后的效果如下:
ORB-SLAM2编译安装以及跑KITTI数据集_第2张图片
ORB-SLAM2编译安装以及跑KITTI数据集_第3张图片

ORB-SLAM2 程序解读
跟踪(Tracking)、建图(Mapping)、重定位(Relocalization)、闭环检测(Loop closing)。
1. System.cc
System.cc是ORB-SLAM2的主程序,也是ORB-SLAM2系统的入口。

System::System()对slam系统的初始化

System::System(const string &strVocFile, const string &strSettingsFile, const eSensor sensor,
               const bool bUseViewer):mSensor(sensor), mpViewer(static_cast<Viewer*>(NULL)), mbReset(false),mbActivateLocalizationMode(false),
        mbDeactivateLocalizationMode(false)
{
    // Output welcome message
    cout << endl <<
    "ORB-SLAM2 Copyright (C) 2014-2016 Raul Mur-Artal, University of Zaragoza." << endl <<
    "This program comes with ABSOLUTELY NO WARRANTY;" << endl  <<
    "This is free software, and you are welcome to redistribute it" << endl <<
    "under certain conditions. See LICENSE.txt." << endl << endl;

    cout << "Input sensor was set to: ";

    if(mSensor==MONOCULAR)
        cout << "Monocular" << endl;
    else if(mSensor==STEREO)
        cout << "Stereo" << endl;
    else if(mSensor==RGBD)
        cout << "RGB-D" << endl;

    //Check settings file
    cv::FileStorage fsSettings(strSettingsFile.c_str(), cv::FileStorage::READ);
    if(!fsSettings.isOpened())
    {
       cerr << "Failed to open settings file at: " << strSettingsFile << endl;
       exit(-1);
    }
    //Load ORB Vocabulary 读取ORB词袋
    cout << endl << "Loading ORB Vocabulary. This could take a while..." << endl;

    mpVocabulary = new ORBVocabulary(); //读取ORB词袋
    bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);
    if(!bVocLoad)
    {
        cerr << "Wrong path to vocabulary. " << endl;
        cerr << "Falied to open at: " << strVocFile << endl;
        exit(-1);
    }
    cout << "Vocabulary loaded!" << endl << endl;

    //Create KeyFrame Database 创建关键帧数据库
    mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);

    //Create the Map 创建地图对象
    mpMap = new Map();

    //Create Drawers. These are used by the Viewer 创建两个显示窗口
    mpFrameDrawer = new FrameDrawer(mpMap); //显示关键帧的窗口
    mpMapDrawer = new MapDrawer(mpMap, strSettingsFile); //显示地图的窗口

    //Initialize the Tracking thread 初始化Tracking对象
    //(it will live in the main thread of execution, the one that called this constructor)它将存在于执行的主线程中
    mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,
                             mpMap, mpKeyFrameDatabase, strSettingsFile, mSensor);

    //Initialize the Local Mapping thread and launch 初始化Local Mapping线程并启动
    mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR);
    mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);//启动线程

    //Initialize the Loop Closing thread and launch
    mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR);
    mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);

    //Initialize the Viewer thread and launch 
    if(bUseViewer)
    {
        mpViewer = new Viewer(this, mpFrameDrawer,mpMapDrawer,mpTracker,strSettingsFile); //初始化窗口
        mptViewer = new thread(&Viewer::Run, mpViewer);//启动,前面有一个是否可视化的判断 bUseViewer?
        mpTracker->SetViewer(mpViewer);
    }

    //Set pointers between threads
    mpTracker->SetLocalMapper(mpLocalMapper);
    mpTracker->SetLoopClosing(mpLoopCloser);

    mpLocalMapper->SetTracker(mpTracker);
    mpLocalMapper->SetLoopCloser(mpLoopCloser);

    mpLoopCloser->SetTracker(mpTracker);
    mpLoopCloser->SetLocalMapper(mpLocalMapper);
}

System.cc中的函数接口

cv::Mat System::TrackStereo(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timestamp)
cv::Mat System::TrackRGBD(const cv::Mat &im, const cv::Mat &depthmap, const double &timestamp)
cv::Mat System::TrackMonocular(const cv::Mat &im, const double &timestamp)// Opencv种的Mat类
void System::ActivateLocalizationMode()
void System::DeactivateLocalizationMode()
bool System::MapChanged()
void System::Reset()
void System::Shutdown()
void System::SaveTrajectoryTUM(const string &filename)
void System::SaveKeyFrameTrajectoryTUM(const string &filename)
void System::SaveTrajectoryKITTI(const string &filename)
int System::GetTrackingState()
vector<MapPoint*> System::GetTrackedMapPoints()
vector<cv::KeyPoint> System::GetTrackedKeyPointsUn()

去畸变函数,去畸变后的像素点存放于mvKeysUn向量之中,具体代码如下:

void Frame::UndistortKeyPoints() //
{
    if(mDistCoef.at<float>(0)==0.0)
    {
        mvKeysUn=mvKeys;
        return;
    }
     // Fill matrix with points
    cv::Mat mat(N,2,CV_32F);
    for(int i=0; i<N; i++)
    {
        mat.at<float>(i,0)=mvKeys[i].pt.x;
        mat.at<float>(i,1)=mvKeys[i].pt.y;
    }
      // Undistort points
    mat=mat.reshape(2);
    cv::undistortPoints(mat,mat,mK,mDistCoef,cv::Mat(),mK);
    mat=mat.reshape(1);
      // Fill undistorted keypoint vector
    mvKeysUn.resize(N);
    for(int i=0; i<N; i++)
    {
        cv::KeyPoint kp = mvKeys[i];
        kp.pt.x=mat.at<float>(i,0);
        kp.pt.y=mat.at<float>(i,1);
        mvKeysUn[i]=kp;
    }
    }
    

拓展:

注释版本ORB_SLAM2
ubuntu如何切换到root用户

参考链接:
ORB_SLAM
ORB_SLAM2安装
linux下 chmod +x的意思?为什么要进行chmod +x
ORB-SLAM2 程序解读
单目slam基础
ORB_SLAM2 KITTI数据集测试
ORB-SLAM2代码阅读笔记(一):从mono_kitti单目运行开始
ORB_SLAM2配置过程

你可能感兴趣的:(ORB-SLAM2编译安装以及跑KITTI数据集)