1. ORB_SLAM2在Win10平台的封装
参考
1.1 更改 ORB_SLAM2项目->属性->常规->WindowsSDK版本为当前VS使用的版本;依次设置配置类型为动态库.dll和静态库.lib,设置编译模式为Release X64,点击生成->编译,生成对应的库文件。
1.2 新建工程,命名为3DRestruct,新建文件夹3rd,3rd/lib,3rd/include,将生成的.lib和.dll放在3rd/lib下,将SLAM.h放在3rd/include下。
1.3 点击视图->其他窗口->属性管理器,右键点击Release|x64->添加现有属性表,添加ORB_SLAM2依赖库。点击依赖库的属性,修改VC++目录中的包含目录和库目录。
1.4 右键项目->属性->VC++目录->包含目录,添加./3rd/include;当前对话窗口->链接器->输入->附加依赖项,添加./3rd/lib/ORB-SLAM.lib;项目->属性->调试->环境,输入
path=xxx/DBoW2/lib/;xxx/g2o/lib/;xxx/Pangolin/lib/;xxx/OpenCV3_1/opencv/build/x64/vc14/bin/;$(ProjectDir)/3rd/lib/;
尤其是最后的$(ProjectDir)/3rd/lib/;,是用来配置ORB-SLAM2动态库的路径。
1.5 编译模式为Release|x64,创建main.cpp(其实就是稍微改动了ORB-SLAM2/Example/stereo/kitti_stereo.cc),需要具备KITTI/xx数据。
#include <SLAM.h>
#include<chrono>
#include<windows.h>
#include<fstream>
#include<iomanip>
using namespace std;
void LoadImages(const string &strPathToSequence, vector<string> &vstrImageLeft,
vector<string> &vstrImageRight, vector<double> &vTimestamps);
int main()
{
// Retrieve paths to images
vector<string> vstrImageLeft;
vector<string> vstrImageRight;
vector<double> vTimestamps;
LoadImages("C:/Users/zhang/Desktop/03", vstrImageLeft, vstrImageRight, vTimestamps);
const int nImages = vstrImageLeft.size();
// Create SLAM system. It initializes all system threads and gets ready to process frames.
slam.init("C:/Users/zhang/Desktop/try/ORB-SLAM2-2/ORB-SLAM2/Run/Vocabulary/ORBvoc.txt", "C:/Users/zhang/Desktop/try/ORB-SLAM2-2/ORB-SLAM2/Run/Setting/KITTI03.yaml", SLAM::eSensor::STEREO);
// 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 imLeft, imRight;
for (int ni = 0; ni < nImages; ni++)
{
// Read left and right images from file
imLeft = cv::imread(vstrImageLeft[ni], CV_LOAD_IMAGE_UNCHANGED);
imRight = cv::imread(vstrImageRight[ni], CV_LOAD_IMAGE_UNCHANGED);
double tframe = vTimestamps[ni];
if (imLeft.empty())
{
cerr << endl << "Failed to load image at: "
<< string(vstrImageLeft[ni]) << endl;
return 1;
}
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
slam.track(imLeft, imRight);
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
double ttrack = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1).count();
vTimesTrack[ni] = ttrack;
// Wait to load the next frame
double T = 0;
if (ni < nImages - 1)
T = vTimestamps[ni + 1] - tframe;
else if (ni > 0)
T = tframe - vTimestamps[ni - 1];
if (ttrack < T)
Sleep((T - ttrack)*1e3); //Linux下#include<unistd.h>调用Usleep为微秒,Win10下#include<windows.h>调用Sleep为毫秒。
}
// Stop all threads即调用SLAM库中的析构函数,不用显示调用
// 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;
return 0;
}
void LoadImages(const string &strPathToSequence, vector<string> &vstrImageLeft,
vector<string> &vstrImageRight, vector<double> &vTimestamps)
{
ifstream fTimes;
string strPathTimeFile = strPathToSequence + "/times.txt";
fTimes.open(strPathTimeFile.c_str());
while (!fTimes.eof())
{
string s;
getline(fTimes, s);
if (!s.empty())
{
stringstream ss;
ss << s;
double t;
ss >> t;
vTimestamps.push_back(t);
}
}
string strPrefixLeft = strPathToSequence + "/image_0/";
string strPrefixRight = strPathToSequence + "/image_1/";
const int nTimes = vTimestamps.size();
vstrImageLeft.resize(nTimes);
vstrImageRight.resize(nTimes);
for (int i = 0; i < nTimes; i++)
{
stringstream ss;
ss << setfill('0') << setw(6) << i;
vstrImageLeft[i] = strPrefixLeft + ss.str() + ".png";
vstrImageRight[i] = strPrefixRight + ss.str() + ".png";
}
}
点击运行,就可以观察到数据库离线跑ORB_SLAM的界面啦!如果不行,报错缺少某个依赖库,就把该.dll放到项目的生成目录下即可。