- 博客(33)
- 收藏
- 关注
原创 ORB-SLAM2 ---- 非线性优化在SLAM中的应用(二)
学到这里我们应该清楚的知道,SLAM的重中之重是优化,在大学中学过最优化或者优化理论的同学知道,优化方法有很多种,而非线性优化的特点是迭代次数少,且精度高,对于不同的精度可以使用不同的优化方法。例如对计算速度要求高,但对精度要求相对不是很高的场合,可以使用高斯-牛顿的方法来进行优化,如果对精度要求高的场合,使用列文伯格-马夸尔方法更加合适。在学习ORBSLAM2比较仔细的会发现,使用的优化全都是列文伯格-马夸尔方法。故这里的讲解重点也放在列文伯格-马夸尔方法上。
2025-01-20 16:24:19
921
1
原创 ORB-SLAM2 ---- 非线性优化在SLAM中的应用(一)
相信大家在学习一段时间SLAM后,会发现两个问题。第一个是代码能看懂,但是不知道为什么这样做(特别是优化部分)。第二个问题就是数学问题,SLAM最难最迷人的部分在于它很多原理归结到了数学问题上。在看优化的时候,因为g2o库的原因,很多数学公式的内在逻辑没有在代码中展现出来,这几篇文章将从最开始的运动模型和观测模型,一步步的推导到优化中用到的列文伯格-马夸尔方法。将非线性优化放在这里将是因为大家已经有了一定的基础,理解起来会更加的容易。
2024-12-07 20:59:01
963
原创 ORB-SLAM2 ---- 词袋模型BOW
词袋模型是ORB-SLAM2中很重要的一个模型,他的作用也有很多,在上述一一列举过,最重要的作用是,在回环检测中匹配相似的图像,曾经该方法是最优的方法之一,现在各种机器学习的发展,例如深度学习,能更高效的完成相似图像的识别,这也是最近深度学习大量运用在SLAM中的原因。
2024-12-07 15:27:57
2202
原创 ORB-SLAM2 ---- LoopClosing::DetectLoop()
该函数是一个具有返回值的函数,返回值类型为bool类型。如果检测到回环就返回true,没有检测到回环就返回false请问。该函数有一个很容易被误解的点,一旦误解,学习的时候就会觉得有些不对劲。该函数是接收了一个从局部见图线程传过来的关键帧,但是判断是否回环的时候,并不是说一定是与该关键帧发生回环,而是每次来一个关键帧就记录一次连续组,当某一个关键帧进来的时候,某一个连续组的长度达到了条件,就会返回true。
2024-12-06 17:29:37
1005
原创 ORB-SLAM2 ----- LocalMapping::KeyFrameCulling()
本函数是局部建图线程的最后一个函数,目的是剔除冗余关键帧。本函数中需要合格的地图点有超过百分之90被观测三次才被标记为冗余关键帧,看起来是一个很难达成的条件,但实际情况中关键帧的剔除是很常见的。造成这种结果的原因是,相机在运动的过程中时间间隔是很短的(帧间隔很短),相机的相对位姿是很小的,所以出现冗余关键帧是很常见的。到此局部建图线程就全部结束了,下面将进入到回环检测线程的。如果大家有什么问题,欢迎沟通交流。
2024-12-05 18:48:30
473
原创 ORB-SLAM2 ----- Optimizer::LocalBundleAdjustment()
本函数是局部建图线程中的优化函数,优化的目标为关键帧的位姿和地图点的位置,这SLAM中建图才是最终的目的,在前面的追踪线程中,每个跟踪函数都有一个优化函数,但这些优化函数都只优化相机的位姿,这样的目的是为了更好的观测周围的环境(地图点),没有急着优化地图点,是因为后面的局部见图线程和闭环线程中会对地图点进行优化,这样可以节省时间,第二点是追踪线程中产生的关键帧和地图点会在后续线程中进行删减,不好的关键帧进行的地图点优化误差也比较大,所以追踪线程中没有对地图点进行优化,而局部见图线程只关注关键帧,而且要进行局
2024-12-05 17:14:59
918
原创 ORB-SLAM2 ----- LocalMapping::SearchInNeighbors()
本函数是为创早的新地图点服务的函数,目的是减少重复的地图点数量,同时优化地图点的坐标(选择观测最多的那个帧对应的地图点保留,本身就是一种优化),我们可以看到,进入到局部见图线程以后,不再使用普通真,而全部使用关键帧,这是因为关键帧是经过筛选的,相对一一般的帧更好,而且这样做的好处还有减少计算量,只用关键帧,可以大大减少匹配次数和难度,在优化时作用更加明显,显著提高效。
2024-11-30 19:55:41
1031
原创 ORB-SLAM2 ----- LocalMapping::ComputeF12和ORBmatcher::CheckDistEpipolarLine
这两个函数在LocalMapping::CreateNewMapPoints()被调用,之所以单独拿出来讲,是因为这两个函都是计算的函数,而且这里是可以用来优化ORB-SLAM2代码的部分,我们完全可以在这部分不用词袋来匹配,直接使用对极约束来进行匹配,匹配效果更好。
2024-11-30 13:55:43
1049
原创 ORB-SLAM2 ---- LocalMapping::MapPointCulling()和LocalMapping::CreateNewMapPoints()
这两个函数是局部见图的核心函数之二,作用是删除不好的地图点,为创造新的地图点。学习局部建图线程和跟踪线程一样,先要知道什么是局部见图,局部建图就是优化局部的地图点,包括删除不好的地图点和增加新的地图点,以及后续对地图点位置的优化调整。大家都知道,SLAM是即时定位与实时建图,在ORB-SLAM2中,追踪线程主要负责即时定位,局部建图线程主要负责实时建图。
2024-11-28 16:21:32
995
原创 ORB-SLAM2 ----Tracking::NeedNewKeyFrame()和Tracking::CreateNewKeyFrame()
这两个函数起到的是承上启下的作用,只有沈城关键帧,才会进入局部建图环节,是连接追踪线程和局部见图线程的函数。这两个函数中,第一个函数是重点,要了解什么时候需要关键帧,知道其中的原理,这个函数也就完全掌握了。
2024-11-27 22:14:16
2071
原创 ORB-SLAM2 ---- Tracking::TrackLocalMap()
本函数是第二层追踪的唯一追踪函数,本函数有两个任务,首要任务就是优化当前帧的位姿,第二个任务就是负责为当前帧找到更多的地图点,同时进行了一个局部建图。这里的第二个任务实质上是为位姿优化服务的,因为地图点越多,优化时的约束也就越多,对位姿的优化也就越好。到这里追踪线程中几个重要的追踪函数就讲完了,如果大家有问题或者发现文章中出现了逻辑错误,欢迎交流指正,互相学习,一起进步。
2024-11-17 20:38:49
820
原创 ORB-SLAM2 ---- Tracking::Relocalization()
本函数是第一层追踪函数中兜底的那个函数,如果重定位追踪都失败了那就只能reset了,这个函数及其重要,其复杂度是三个追踪中最大的,所以不到万不得已是不会启动的。我们知道追踪的目的主要是找到新来帧的位姿,所以在丢掉位姿时,首要的事情就是找一个参考系,而这样的参考系最好是具有代表性的“关键帧”,所有在重定位中,先找一个和本帧具有高度一致性的关键帧成了重定位的关键。本函数基本上就是找到合适的关键帧,然后根据该关键帧找到本帧的位姿。三大追踪在这里就全都结束了,如果有三大追踪之间逻辑关系还没有梳理清楚,欢迎交流,
2024-11-16 21:08:23
698
原创 ORB-SLAM2 ---- Tracking::TrackWithMotionModel()
本函数为第一层追踪的三大追踪方法之一的恒速追踪模型,也是用到最多的追踪方式,他的特征匹配非常的简单,匹配次数非常的少,之和自己附件的点进行匹配,所以会出现漏匹配的情况,在漏匹配比较多的时候,会造成匹配点数不符合要求这样的尴尬情况,这时就需要用更强大的追踪方式来进行追踪(当然,这样做的代价更大,比如说匹配次数会增加,这也是为什么优先恒速追踪模型),而且恒速追踪模型因为实在附近进行匹配点,所以他一旦匹配成功,可靠性就会很强,这也是为什么初始话匹配器时(ORBmatcher matcher(0.9,true);
2024-11-16 17:03:54
1067
原创 ORB-SLAM2 ---- Tracking::TrackReferenceKeyFrame()
本函数是第一次追踪的三大追踪之一的-----参考关键帧追踪,他的追踪能里很强,如果参考关键帧追踪都失败了,那只能进行重定位了。
2024-11-12 20:00:53
1132
原创 ORB-SLAM2 ---- Tracking::StereoInitialization()
本函数为双目初始化,其中调用了数十个函数,主要来源于Frame.cc ORBmatcher.cc MapPoint.cc KeyFrame.cc ,这也是主线程函数的特点,大量的调用其他类中的函数,目的是让主线程看起来简单,能很好的梳理主线程的逻辑。本文中的标注均为本人在看代码时写的,若对其有疑问或发现问题,欢迎大家交流。
2024-10-22 23:39:37
896
原创 ORB-SLAM2 ---- Tracking::Track()
此函数为跟踪线程的最主要部分,在不同条件下调用不同的跟踪方式,然后进行局部建图跟踪,最后保存这此跟踪的成果(相机的位姿等),而且本函数除了明线外,还参与了贯穿三条主线程的一条暗线,因为读者后读到这里还未学完三个主线程,这里就给读者留下一个悬念,在后续文章中会讲到,如果有需要也欢迎大家和本人交流。
2024-10-21 21:29:06
864
原创 ORB -SLAM2 ---- Tracking::Tracking和GrabImageStereo
这两个函数在追踪线程中有着极为重要的作用,Tracking::Tracking在初始化追踪线程时用到,GrabImageStereo() 中调用的Track();是追踪线程的主体,后续会详细讲解追踪线程中的其他函数。如果有什么问题或者建议,欢迎大家交流。
2024-10-21 20:25:07
883
原创 ORB-SLAM2 ---- Frame中在主函数中被调用的函数
这四个函数不在Frame.cc中调用,但是作用很重要,帧在三个线程中被普遍应用,如果帧的内容不熟悉,学三个主线程时会有很多的疑问。这两个函数因为比较简单,并且本人对代码做了很详细的标注,所以没有过多的函数讲解,若大家有疑问欢迎讨论。
2024-10-21 19:29:09
504
原创 ORB-SLAM ---- Frame::ComputeImageBounds和Frame::AssignFeaturesToGrid()
本篇主要讲解去畸变函数,和将特征点分配到相应网格的函数
2024-10-14 10:15:25
858
原创 ORB-SLAM ---- Frame::ComputeStereoMatches()
此方法核心是调用 cv::norm(IL,IR,cv::NORM_L1) 函数,此方法在左目特征点附近开辟一定区域IL,然后在对应粗匹配的特征点附近取一个区域IR,将IR在一定区域内滑动,找到IL与IR之间的L1范数最小的那个IR,然后在这个区域的中心找到一个像素点(此像素点即为最匹配的像素点),找到其左右像素点对应的IR,根据三点法求到dist最小的那个亚像素级的点。我们设最佳匹配像素点和其左右点的坐标为(x1,y1),(x2,y2),(x3,y3),其中x2是最佳匹配点。
2024-10-13 21:56:37
958
原创 ORB-SLAM2 ---- Frame::ExtractORB和Frame::UndistortKeyPoints
本篇文章主要讲解,帧的提取特征点和特征点(坐标)去畸变
2024-10-13 00:47:25
1012
原创 ORB-SLAM2 ---- Frame内容梳理(Frame.cc)
本文中涵盖了Frame.cc中所有的函数, 这篇文章的目的是梳理此文件,让读者知道此文件的逻辑,并推荐一个合理的学习顺序,如有不合理或错误的地方欢迎指正交流。
2024-10-11 20:41:40
813
原创 ORB-SLAM2 ---- ORBextractor::operator()
仿函数(函数对象,Functor)是在C++中通过重载operator()运算符的类或结构体,使得其对象可以像普通函数一样被调用。本质:是一个类或结构体的对象,通过重载()运算符模仿函数的调用行为。状态:仿函数可以保存状态(成员变量),与普通函数相比更加灵活。用法:可以像函数一样调用对象,常用于STL算法(如std::sort)。示例(调用仿函数用类的名称,而不是operator()):// 定义一个仿函数类public:// 重载()运算符Add add;// 创建仿函数对象。
2024-10-09 08:27:07
840
原创 ORB-SLAM2 ---- ORBextractor::ComputeKeyPointsOctTree
FAST ()角点提取器来提取角点(角点优先作为特征点),如果该网格内没有角点,就降低阈值进行提取特征值,特征值提取好后,遍历这些提取出来的特征值,将特征点的坐标转换到【坐标边界】下的坐标。这段代码前面的部分,在补充分配单元格的内容,简单来说就是分到最后一行不足30了,就委屈一下最后一行列少分配一些,后续调用。是此函数的基础,此函数是除主函数外最重要的一个函数,此函数的主要作用是对特征点进行处理(提取,分配,计算方向信息)来分配提取出来的特征点,然后遍历这些特征点,将其坐标转换到当前图层图像坐标系下。
2024-10-08 21:39:01
1864
原创 ORB-SLAM2 ---- ORBextractor::DistributeOctTree
从上图我们知道,分完节点后可能一个节点中有多个特征点,这样会导致特征点过于密集,会影响建图的精度,接下来这段代码的含义是,每个节点内保留一个应答最大的特征带点,并将其装入容器内,作为函数的返回值。是此函数的基础,此函数的作用是使用四叉树法对一个图像金字塔图层中的特征点进行平均和分发,这个函数代码量相对较大,但是他在特征提取中是一个非常重要的函数,读者一定要认真仔细的学习。因为此函数代码量较大,我们分几段来讲解。
2024-10-08 20:27:38
1179
原创 ORB-SLAM2 ---- ExtractorNode::DivideNode
将提取器节点分成4个子节点,同时也完成图像区域的划分、特征点归属的划分,以及相关标志位的置位,会在分配特征点时被调用。
2024-10-08 17:50:55
277
原创 ORB-SLAM2 ---- computeOrbDescriptor
【代码】ORB-SLAM2 ---- computeOrbDescriptor。
2024-10-08 16:56:49
208
原创 ORB-SLAM2 ---- ORBextractor::ComputePyramid
【代码】ORB-SLAM2 ---- ORBextractor::ComputePyramid。
2024-10-08 09:00:45
362
原创 ORB-SLAM2 ---- ORBextractor::ORBextractor
构造函数在Tracking中会new一个ORBextractor(),并且初始化,后续可以使用此函数中的容器:1. 装每层特征点个数的容器『mnFeaturesPerLevel』2. 装灰度圆边界的容器『umax[v]』
2024-10-07 23:05:10
352
1
原创 ORB-SLAM2 ---特征特提取梳理(ORBextractor.cc)
1. 图像金字塔分层2. 计算每层金字塔的特征点数量3. 每个图层分成30*30的网格4. 在每个网格里面提取特征点5. 用四叉树的方法分配特征点6. 每个节点中取应答最大的那个特征点7. 计算所有特征点的方向信息和描述子8. 将所有处理好的特征点放入容器中。
2024-10-07 15:56:47
744
4
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人