ORB_SLAM3 Track线程详解

概述

ORB-SLAM3 是第一个同时具备纯视觉(visual)数据处理、视觉+惯性(visual-inertial)数据处理、和构建多地图(multi-map)功能,支持单目、双目以及 RGB-D 相机,同时支持针孔相机、鱼眼相机模型的 SLAM 系统。

主要创新点:

1.在 IMU 初始化阶段引入 MAP。该初始化方法可以实时快速进行,鲁棒性上有很大的提升(在大的场景还是小的场景,不管室内还是室外环境均有较好表现),并且比当前的其他方法具有 2-5 倍的精确度的提升。
2.基于一种召回率大大提高的 place recognition(也就是做回环检测,与历史数据建立联系)方法实现了一个多子地图(multi-maps)系统。ORB-SLAM3 在视觉信息缺乏的情况下更具有 long term 鲁棒性,当跟丢的时候,这个时候就会重新建一个子地图,并且在回环的时候与之前的子地图进行合并。ORB-SLAM3 是第一个可以重用历史所有算法模块的所有信息的系统。

主要结论:

在所有 sensor 配置下,ORB-SLAM3 的鲁棒性与现在的发表的各大系统中相近,精度上有了显著的提高。尤其使用Stereo-Inertial SLAM,在 EuRoC 数据集的平均误差接近 3.6 cm,在一个偏向 AR/VR 场景的 TUM-VI 数据集的平均误差接近 9mm。
ORB_SLAM3系统框图
在这里插入图片描述
ORB_SLAM3启动入口在Examples文件夹中,包含单目、双目、RGB-D,及其惯性组合。本文以双目+惯性作为例子,介绍ORB_SLAM3 Track线程。
Track线程在System.cc完成创建,主要完成读取配置文件参数./Examples/Stereo-Inertial/Realsense_D435i.yaml。在主文件stereo_inertial_realsense_D435i.cc中SLAM.TrackStereo()–>mpTracker->GrabImageStereo–>Track()开启跟踪。

一、读取相机数据

根据相机类型,确定是否需要needToRectify和needToResize,否则直接读取数据放入imLeftToFeed/imRightToFeed。

cv::Mat imLeftToFeed, imRightToFeed;
if(settings_ && settings_->needToRectify()){
    
    
	cv::Mat M1l = settings_->M1l();
	cv::Mat M2l = settings_->M2l();
	cv::Mat M1r = settings_->M1r();
	cv::Mat M2r = settings_->M2r();

	cv::remap(imLeft, imLeftToFeed, M1l, M2l, cv::INTER_LINEAR);
	cv::remap(imRight, imRightToFeed, M1r, M2r, cv::INTER_LINEAR);
}
else if(settings_ && settings_->needToResize()){
    
    
	cv::resize(imLeft,imLeftToFeed,settings_->newImSize());
	cv::resize(imRight,imRightToFeed,settings_->newImSize());
}
else{
    
    
	imLeftToFeed = imLeft.clone();
	imRightToFeed = imRight.clone();
}

二、检查模式是否改变(关闭局部建图线程仅进行追踪线程)

模式是否改变,取决于viewer中是否进行了设置ActivateLocalizationMode。
若mbActivateLocalizationMode为true,则关闭局部建图线程,进跟踪模式;
若mbDeactivateLocalizationMode为true,则同时进行局部建图、跟踪。

// Check mode change
{
    
    
	// 独占锁,主要是为了mbActivateLocalizationMode和mbDeactivateLocalizationMode不会发生混乱
	unique_lock<mutex> lock(mMutexMode);
	// mbActivateLocalizationMode为true会关闭局部地图线程,仅跟踪模式
	if(mbActivateLocalizationMode)
	{
    
    
		mpLocalMapper->RequestStop();

		// Wait until Local Mapping has effectively stopped
		while(!mpLocalMapper->isStopped())
		{
    
    
			usleep(1000);
		}
		// 局部地图关闭以后,只进行追踪的线程,只计算相机的位姿,没有对局部地图进行更新
		mpTracker->InformOnlyTracking(true);
		// 关闭线程可以使得别的线程得到更多的资源
		mbActivateLocalizationMode = false;
	}
	if(mbDeactivateLocalizationMode)
	{
    
    
		mpTracker->InformOnlyTracking(false);
		mpLocalMapper->Release();
		mbDeactivateLocalizationMode = false;
	}
}

三、检查地图是否重置

是否需要重置地图条件主要有:viewer中设置,跟踪线程中如果认为imu有问题重置等等,主要是根据跟踪线程中局部地图和imu相关状态进行处理。

// Check reset
{
    
    
	unique_lock<mutex> lock(mMutexReset);
	if(mbReset)
	{
    
    
		mpTracker->Reset();
		mbReset = false;
		mbResetActiveMap = false;
	}
	else if(mbResetActiveMap)
	{
    
    
		mpTracker->ResetActiveMap();
		mbResetActiveMap = false;
	}
}

四、如果传感器类型为IMU_STEREO,读取imu数据

读取imu数据接口为mpTracker->GrabImuData(vImuMeas[i_imu])

if (mSensor == System::IMU_STEREO)
	for(size_t i_imu = 0; i_imu < vImuMeas.size(); i_imu++)
		mpTracker->GrabImuData(vImuMeas[i_imu]);

数据存放在mlQueueImuData链表中

void Tracking::GrabImuData(const IMU::Point &imuMeasurement)
{
    
    
    unique_lock<mutex> lock(mMutexImuQueue);
    mlQueueImuData.push_back(imuMeasurement);
}

五、根据双目计算相机位姿

// std::cout << "start GrabImageStereo" << std::endl;
Sophus::SE3f Tcw = mpTracker->GrabImageStereo(imLeftToFeed,imRightToFeed,timestamp,filename);

进入GrabImageStereo

1.将RGB、RGBA图像转化为灰度图像

// step 1 :将RGB或RGBA图像转为灰度图像
if(mImGray.channels()==3)
{
    
    
	//cout << "Image with 3 channels" << endl;
	if(mbRGB)
	{
    
    
		cvtColor(mImGray,mImGray,cv::COLOR_RGB2GRAY);
		cvtColor(imGrayRight,imGrayRight,cv::COLOR_RGB2GRAY);
	}
	else
	{
    
    
		cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY);
		cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGR2GRAY);
	}
}

2.双目模式特征提取、匹配,得到当前帧信息mCurrentFrame

主要完成:

(1)ORB特征提取ORBextractor
(2)ORB特征匹配ComputeStereoMatches()
// 双目模式,注意跟两个相机模式区分开
if (mSensor == System::STEREO && !mpCamera2)
	mCurrentFrame = Frame(
		mImGray,                // 左目图像
		imGrayRight,            // 右目图像
		timestamp,              // 时间戳
		mpORBextractorLeft,     // 左目特征提取器
		mpORBextractorRight,    // 右目特征提取器
		mpORBVocabulary,        // 字典
		mK,                     // 内参矩阵
		mDistCoef,              // 去畸变参数
		mbf,                    // 基线长度
		mThDepth,				// 远点,近点的区分阈值
		mpCamera);				// 相机模型
else if(mSensor == System::STEREO && mpCamera2)
	mCurrentFrame = Frame(mImGray,imGrayRight,timestamp,mpORBextractorLeft,mpORBextractorRight,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera,mpCamera2,mTlr);
else if(mSensor == System::IMU_STEREO && !mpCamera2)
	mCurrentFrame = Frame(mImGray,imGrayRight,timestamp,mpORBextractorLeft,mpORBextractorRight,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera,&mLastFrame,*mpImuCalib);
else if(mSensor == System::IMU_STEREO && mpCamera2)
	mCurrentFrame = Frame(mImGray,imGrayRight,timestamp,mpORBextractorLeft,mpORBextractorRight,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera,mpCamera2,mTlr,&mLastFrame,*mpImuCalib);

3.跟踪Track

跟踪主要完成估计运动,跟踪局部地图,跟踪过程包括恒速模型跟踪,参考关键帧跟踪,局部地图跟踪。
该部分内容较多,只用文字的方式很难表达清楚,也显得太长,这部分等想到好的表达方式再填坑。

终于水完了。。。。

参考:

https://github.com/UZ-SLAMLab/ORB_SLAM3

猜你喜欢

转载自blog.csdn.net/u010196944/article/details/129126089