rgdb_tum.cc的框架
代码大致思路
- LoadImages()加载图像——判断rgb图是否存在——判断rgb图与depth图数量是否对应相同。
- ORB_SLAM2::System SLAM()初始化,创建SLAM系统,并初始化各个线程。
- 遍历每一对RGB图和depth图【读取RGB图和depth图,读取时间戳(vTimestamps存储了时间戳,实际上就是存储了数据文件的每一幅图像的采集时间)——判断文件是否读取成功——SLAM.TrackRGB()将图片转给system处理,在这里从主线程进入tracking线程——计算track一帧的时间——计算两幅图像的采集时间之差,即采集一帧图像的时间——比较追踪时间和采集时间,通过休眠保持同步运行】
- 关闭系统对象——计算追踪总时间以及时间中位数和平均数——SaveTrajectoryTUM()保存相机轨迹和SaveKeyFrameTrajectoryTUM()关键帧轨迹
具体
1.LoadImages 加载图像
* @param strAssociationFilename 关联文件的访问路径
* @param vstrImageFilenamesRGB 彩色图像路径序列
* @param vstrImageFilenamesD 深度图像路径序列
* @param vTimestamps 时间戳
2.实例化SLAM对象,这里初始化了很多线程
3.SLAM.TrackMonocular(im,tframe) 是代码的核心,特征点提取以及均匀化和描述子计算都在这里实现,同时还有整个系统是如何实现跟踪的,还有就是关键帧的选择方式
4.SLAM.shutdown() 关闭所有线程
5.记录跟踪图片的时间
6.将相机轨迹保存
传入参数
int main(int argc, char **argv)
argc 是 argument count的缩写,表示传入main函数的参数个数;argv 是 argument vector的缩写,表示传入main函数的参数序列或指针,并且第一个参数 argv[0] 一定是程序的名称,并且包含了程序所在的完整路径
五个参数argv[0-4]:可执行文件,词袋文件,tum配置文件,数据集的路径,左右目的对准文件
代码阅读
1 首先判断参数是否符合五个参数,符合就继续
2 处理图像
step1. 读取图片及左右目关联信息
按顺序存放需要读取的彩色图像、深度图像的路径,以及对应的时间戳的变量
main()开始定义了三个容器分别存放每张图片的路径、图片的深度路径和时间戳
vector<string> vstrImageFilenamesRGB; //每张图片存放路径
vector<string> vstrImageFilenamesD; //深度图像路径存放路径
vector<double> vTimestamps; //每张图片时间戳
通过LoadImages函数,将图片和时间戳加载进容器中
// 获取图像序列中每一张图像与深度图的访问路径和时间戳
void LoadImages(const string &strAssociationFilename, vector<string> &vstrImageFilenamesRGB,
vector<string> &vstrImageFilenamesD, vector<double> &vTimestamps)
LoadImages()加载图像:读取图像的associate.txt文件,里面每一行有四个数据:rgb采集时间,rgb文件名,depth采集时间,depth文件名。其中文件名都是以采集时间命名的。——整行读取——第一个数据转换为double后存入vTimestamps向量中,第二个数据存入vstrImageFilenamesRGB中,第三个数据丢弃,第四个数据存入vstrImageFilenamesD中。
step2. 检查图片文件及输入文件的一致性
判断图片是否为空与深度图和彩色图是否一致
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;
}
step3. 创建SLAM对象,它是一个 ORB_SLAM2::System 类型变量
实例化一个SLAM对象 传入四个参数,即词典文件路径,配置文件路径、传感器类型、是否可视化
ORB_SLAM2::System SLAM(argv[1],argv[2],ORB_SLAM2::System::RGBD,true);
System的构造函数:
System::System(const string &strVocFile, //词典文件路径
const string &strSettingsFile, //配置文件路径
const eSensor sensor, //传感器类型
const bool bUseViewer): //是否使用可视化界面
mSensor(sensor), //初始化传感器类型
mpViewer(static_cast<Viewer*>(NULL)), //空。。。对象指针? 视觉SLAMch6 g2o代码中使用过,将指向基类的指针转化为指向派生类的指针
mbReset(false), //无复位标志
mbActivateLocalizationMode(false), //没有这个模式转换标志
mbDeactivateLocalizationMode(false) //没有这个模式转换标志
{
之后创建一个容器vTimesTrack用来保存跟踪时间 (?)
step4. 遍历图片,进行SLAM
首先遍历所有的图片
for(int ni=0; ni<nImages; ni++)
{....}
读取图像与时间戳
//CV_LOAD_IMAGE_UNCHANGED :不加改变的载入原图
imRGB = cv::imread(string(argv[3])+"/"+vstrImageFilenamesRGB[ni],CV_LOAD_IMAGE_UNCHANGED); //图像
imD = cv::imread(string(argv[3])+"/"+vstrImageFilenamesD[ni],CV_LOAD_IMAGE_UNCHANGED); //深度图
double tframe = vTimestamps[ni]; //时间戳
判断是否读取正确,正确就记录时间,并将图像和时间戳传入Tracking线程
SLAM.TrackRGBD(imRGB,imD,tframe);
之后计算track耗时并保存,和下一帧时间戳对比,计算等待时间
当所有的图片遍历结束,停止slam所有线程SLAM.Shutdown()
对单张图片track消耗时间进行排序,并计算中位时间值和平均时间
最后调用函数保存轨迹