本文共 4343 字,大约阅读时间需要 14 分钟。
由于12月末的时候掏钱买了个orbslam2源码讲解的视频,虽然每一天也有陆陆续续看一点,但是越到后面看的越懵,因为orbslam2的代码还是比较复杂的。于是我打算简单记录一个代码框架,就是文件结构、伪代码和思路之类的,不涉及具体细节,旨在对整个slam框架的思路有个了解。而且网上对orbslam2的好的解说有太多了,我也就不班门弄斧了。这篇博文也就相当于一个学习笔记,比较粗糙,但对照着这个结构去看相关视频和博客以及源码,我觉得让我的思绪更加有条理,希望对大家有用。而且这个应该一直在更,取决于我视频看到哪。
----------------------------------手动分割线-------------------------------------
main{ LoadImages(); ORB_SLAM2::System SLAM(); for each in images{ SLAM.TrackMonocular(each); }}
System(){ Load_OrbVocabulary(); new KeyFrameDatabase; new Map; // new thread new Tracking(); new LocalMapping(); new LoopClosing(); }
Tracking(){ Load_CameraIntrincs(); new ORBextractor();}
LocalMapping::Run(){ while(1){ if(CheckNewKeyFrames()){ ProcessNBewKeyFrame(); MapPointCulling(); CreateNewMapPoints(); if(!CheckNewKeyFrame() &&!stopRequested()){ // local BA Optimizer::LocalBundleAdjustment(); KeyFrameCulling(); } } }}
ORBextractor(){ 初始化图像金字塔(尺度、方差、特征点数分配); // for orientation 求umax;}
LoopClosing::Run(){ while(1){ if(CheckNewKeyFrames()){ if(DetectLoop()){ if(ComputeSim3()){ CorrectLoop(); } } } }}
SLAM.TrackMonocular(){ // calculate Tcw GrabImageMonocular();}
GrabImageMonocular(){ if(not initialized) Frame(init_ORBextractor); else Frame(ORBextractor); Track();}
Frame(){ ExtractORB(); AssignFeaturesToGrid();}
ExtractORB(){ // extract orb features (*xxx)();}
ORBextractor::operator()(){ // 构建图像金字塔 ComputePyramid(image); ComputeKeyPointsOctTree(); for each levels{ GaussianBlur(); computeDescriptors(); }}
ComputeKeyPointsOctTree(){ for each levels{ for each grids{ Fast(); } DistributeOctTree(); } for each levels{ computeOrientation(); }}
// 四叉树平均分配特征点DistrbuteOctTree(){ 1. 按照图像大小初始化节点 2. 节点分裂为4个节点,每个节点占母节点区域的1/4,也就是上下左右格子,并删除母节点。 3. 如果该节点特征点多于阈值,重复2。 4. 最后只取所有节点中响应值最大的特征点。}
// 这里用到了umaxcomputeOrientation(){ for each keypoints{ keypoint->angle = IC_Angle(); }}// 这里顺带看IC_Angle, 不分级了static float IC_Angle(){ // 使用灰度质心法计算特征点方向 for v = 1:r { // r半径 for u = -umax ~ umax { // 计算m_10 // 计算m_01 } } return fastAtan2(m_01, m_10);}
computeDescriptors(){ for i = 1:keypoints.size(){ computeOrbDescriptor(); }}computeOrbDescriptor(){ for (i = 0; i < 32; i++){ // 32位 brief描述子 // 描述子旋转 // 比大小构成二进制描述子 }}
Track(){ if(not initialized) MonocularInitialization(); else{ if(state == OK) { // replace map points CheckReplacedInLastFrame(); if(no motion model || not long after initialization) TrackReferenceKeyFrame(); else{ if(! TrackWithMotionModel) TrackReferenceKeyFrame(); } }else Relocalization(); if(TrackLocalMap()){ // if tracking was good, check if insert a keyframe if(NeedNewKeyFrame()) CreateNewKeyFrame(); } } }
MonocularInitalization(){ ORBmatcher matcher(); matcher.SearchForInitialization(); // initialize via F or H mpInitializer->Initialize(); // initial monocular map CreateInitMapMonocular();}
转载地址:http://hoklf.baihongyu.com/