ORB-SLAM2代码学习1 rgdb_tum.cc

论文翻译
参考1
参考2

rgdb_tum.cc的框架

代码大致思路

  1. LoadImages()加载图像——判断rgb图是否存在——判断rgb图与depth图数量是否对应相同。
  2. ORB_SLAM2::System SLAM()初始化,创建SLAM系统,并初始化各个线程。
  3. 遍历每一对RGB图和depth图【读取RGB图和depth图,读取时间戳(vTimestamps存储了时间戳,实际上就是存储了数据文件的每一幅图像的采集时间)——判断文件是否读取成功——SLAM.TrackRGB()将图片转给system处理,在这里从主线程进入tracking线程——计算track一帧的时间——计算两幅图像的采集时间之差,即采集一帧图像的时间——比较追踪时间和采集时间,通过休眠保持同步运行】
  4. 关闭系统对象——计算追踪总时间以及时间中位数和平均数——SaveTrajectoryTUM()保存相机轨迹和SaveKeyFrameTrajectoryTUM()关键帧轨迹
    ORB-SLAM2代码学习1 rgdb_tum.cc_第1张图片

具体

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消耗时间进行排序,并计算中位时间值和平均时间
最后调用函数保存轨迹

你可能感兴趣的:(SLAM,学习,计算机视觉,人工智能)