本文采用的是rgbdtum.cc的代码
当然整体的代码构建是由众多代码组成的,但是本文目标是负基础的同学,因此首先看一看.cc主程序到底是干吗的
#include<iostream>
#include<algorithm>
#include<fstream>
#include<chrono>
#include<opencv2/core/core.hpp>
#include<System.h>
using namespace std;
///这里是头文件,也可以看到除了一些标准库,最重要的是有一个自己写的<System.h>头文件,当然这部分也是主要系统的构成
void LoadImages(const string &strAssociationFilename, vector<string> &vstrImageFilenamesRGB,
vector<string> &vstrImageFilenamesD, vector<double> &vTimestamps);
//定义了一个读图像的程序,这个程序在末尾有
int main(int argc, char **argv)
{
if(argc != 5)告诉你怎么用的
{
cerr << endl << "Usage: ./rgbd_tum path_to_vocabulary path_to_settings path_to_sequence path_to_association" << endl;
return 1;
}
// Retrieve paths to images
vector<string> vstrImageFilenamesRGB;
vector<string> vstrImageFilenamesD;
vector<double> vTimestamps;
string strAssociationFilename = string(argv[4]);
LoadImages(strAssociationFilename, vstrImageFilenamesRGB, vstrImageFilenamesD, vTimestamps);
构建了一些cetor类型的容器,读完了图像
// Check consistency in the number of images and depthmaps
int nImages = vstrImageFilenamesRGB.size();
if(vstrImageFilenamesRGB.empty())
{
cerr << endl << "No images found in provided path." << endl;
return 1;
}
else if(vstrImageFilenamesD.size()!=vstrImageFilenamesRGB.size())
{
cerr << endl << "Different number of images for rgb and depth." << endl;
return 1;
}
//看看图像有没有,RGBD与RGB的图像数量是否一样
// Create SLAM system. It initializes all system threads and gets ready to process frames.
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::RGBD,true);
初始化了一个ORB_SLAM3空间下的::System SLAM函数,当然,这个函数里面有很多东西,大部分都是初始化的内容。后面会进一步分析。
float imageScale = SLAM.GetImageScale();
// 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 imRGB, imD;
//看到for,基本上就知道大循环来了,所以导航过程也在这里循环里面,需要明白的是,整体的、slam的过程就是不断的前后帧匹配的过程。
for(int ni=0; ni<nImages; ni++)
{
// Read image and depthmap from file
imRGB = cv::imread(string(argv[3])+"/"+vstrImageFilenamesRGB[ni],cv::IMREAD_UNCHANGED); //,cv::IMREAD_UNCHANGED);
imD = cv::imread(string(argv[3])+"/"+vstrImageFilenamesD[ni],cv::IMREAD_UNCHANGED); //,cv::IMREAD_UNCHANGED);
double tframe = vTimestamps[ni];
if(imRGB.empty())
{
cerr << endl << "Failed to load image at: "
<< string(argv[3]) << "/" << vstrImageFilenamesRGB[ni] << endl;
return 1;
}
if(imageScale != 1.f)
{
int width = imRGB.cols * imageScale;
int height = imRGB.rows * imageScale;
cv::resize(imRGB, imRGB, cv::Size(width, height));
cv::resize(imD, imD, cv::Size(width, height));
}
#ifdef COMPILEDWITHC11
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.TrackRGBD(imRGB,imD,tframe);
这个部分就是SLAM定位的主程序了,显然虽然这里只有一行,但是其实是成千上万行。
#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
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();
///由于slam中使用的是new这样的方法保证了内存不会自动关闭,因此对应的需要手动关闭
// 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.SaveTrajectoryTUM("CameraTrajectory.txt");
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");
//保存关键帧,便于后续的evo软件进行分析
return 0;
}
void LoadImages(const string &strAssociationFilename, vector<string> &vstrImageFilenamesRGB,
vector<string> &vstrImageFilenamesD, vector<double> &vTimestamps)
{
ifstream fAssociation;
fAssociation.open(strAssociationFilename.c_str());
while(!fAssociation.eof())
{
string s;
getline(fAssociation,s);
if(!s.empty())
{
stringstream ss;
ss << s;
double t;
string sRGB, sD;
ss >> t;
vTimestamps.push_back(t);
ss >> sRGB;
vstrImageFilenamesRGB.push_back(sRGB);
ss >> t;
ss >> sD;
vstrImageFilenamesD.push_back(sD);
}
}
}
//也可以看到上面的load函数使用的是stringstream 这样的流,通过<<与>>进行赋值,大家可以自行百度搜索。
/至此,tum_cc就说完了,基本上可以归结为以下几点
//1.查看图像的路径与数量
//2.初始化
//3.在大循环里面计算运动
//4.保存数据
ORBSLAM3代码负基础解析
最新推荐文章于 2024-08-21 15:58:14 发布
该文详细介绍了如何使用RGBDTUM.cc代码来处理RGB-D图像序列,通过ORB_SLAM3框架进行SLAM(SimultaneousLocalizationAndMapping)。首先加载图像和深度图,接着初始化SLAM系统,然后在循环中处理每一帧图像进行跟踪。程序还包含了时间统计和轨迹保存功能。
摘要由CSDN通过智能技术生成