ORBSLAM2の概要-LocalMappingスレッド

序文

この記事では、残りのORBSLAM2データを組み合わせて、ORBLSAM2ソースコードに注釈を付けます。KnowledgePlanetとBubble Robotのおかげで、Wu Bo!
ソースコードは、Knowledge Planet Xiaoliu etalの注釈付きバージョンです。

LocalMappingスレッドは、主にTrackingスレッドから渡されたキーフレームを処理するために使用されます。
個人的な理解は次のとおりです。
追跡スレッドが現在のフレームの追跡と、このフレームのマップポイントの関連情報を完了する限り。
LocalMappingでこの新しいキーフレームを処理するだけ
です。
注:新しいキーフレームはバッファキューで処理されます。処理後、バッファキューから削除する必要があります。
LocalMappingのメインプロセスを次の図に示します。
ここに画像の説明を挿入します
上記のプロセスは、
LocalMapping.cppのスレッドメイン関数void LocalMapping :: Run()に具体的に反映されています。

/**
 * 线程主函数:简单说明一下localmapping线程的主函数
 * 首先mbFinished为线程主函数运行与否的表示 为false说明在运行
 * LocalMapping线程处理的关键帧都是Tracking线程发过的
 * 从tracking线程那边传入一个关键帧,现在想把这个新的关键帧放进关键帧队列里面去,所以肯定在处理的时候不想有其他帧加进来
 *
 *主循环
 * Step 1 告诉Tracking,LocalMapping正处于繁忙状态,请不要给我发送关键帧打扰我,只处理队列里的关键帧----SetAcceptKeyFrames(false);//这里就是不接受关键帧
 * if---等待处理的关键帧列表不为空----CheckNewKeyFrames()
 *          Step 2 处理列表中的关键帧,包括计算BoW、更新观测、描述子、共视图,插入到地图等
 *                 ProcessNewKeyFrame() 处理新关键帧---更新mappoints 与keyframes的关联以及UpdataConnections()
 *
 *          Step 3 根据地图点的观测情况剔除质量不好的地图点
 *                   MapPointCulling();
 *                   剔除地图中新添加的但质量不好的MapPoints:
 *                    a.IncreaseFound / IncreaseVisible < 25%
 *                    b.观测到该点的关键帧太少
 *          Step 4 当前关键帧与相邻关键帧通过三角化产生新的地图点,使得跟踪更稳---因为上一步踢掉了一些不好的地图点
 *                 CreateNewMapPoints() 运动过程中和共视程度比较高的关键帧通过三角化恢复出一些MapPoints
 *          直到 已经处理完队列中的最后的一个关键帧
 *          Step 5 检查并融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点---融合地图点其实就是 ,举个例子,对于当前关键帧之前有两个帧(帧n[更靠近当前关键帧的那个帧] 与 帧m)
 *                                                                                              当前关键帧与帧n匹配的特征点对应的地图点 可能与 当前关键帧与帧m匹配的特征点对应的地图点不是一个地图点(因为误差的累计)
 *                                                                                              所以要融合地图点,我们以 当前关键帧与帧n匹配的特征点对应的地图点为准(说是融合其实就是替换)
 *                  SearchInNeighbors(); 检查并融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点
 *          如果已经处理完队列中的最后的一个关键帧,并且闭环检测没有请求停止LocalMapping
 *          Step 6 当局部地图中的关键帧大于2个的时候进行局部地图的BA, 和当前关键帧相连的关键帧(应该就是共视程度比较高的关键帧)及MapPoints做局部BA优化
 *          Step 7 检测并剔除当前帧相邻的关键帧中冗余的关键帧
 *                 冗余的判定:该关键帧的90%的地图点可以被其它关键帧观测到(说明这个帧是多余的,因为其他的三个以上的帧看到这个关键帧mappoints的90%了 )
 *          Step 8 将当前帧加入到闭环检测队列中
 *          查看是否有复位线程的请求
 *          告诉Tracking,LocalMapping 现在不忙了----SetAcceptKeyFrames(true);//接收关键帧
 *          如果当前线程已经结束了就跳出主循环 不然就等---usleep(3000)
 *
 * else----当要终止当前线程的时候
 *    如果还没有结束利索,那么等-------isStopped() && !CheckFinish()
 *                                usleep(3000)
 *    然后确定终止了就跳出这个线程的主循环
 *         if(CheckFinish())
 *              break;
 *跳出主循环后
 *设置线程已经终止---SetFinish();
 */
// 线程主函数
void LocalMapping::Run()
{
    
    

    // 标记状态,表示当前run函数正在运行,尚未结束
    mbFinished = false;
    // 主循环
    while(1)
    {
    
    
        // Tracking will see that Local Mapping is busy
        // Step 1 告诉Tracking,LocalMapping正处于繁忙状态,请不要给我发送关键帧打扰我,处理队列;里的关键帧
         LocalMapping线程处理的关键帧都是Tracking线程发过的
        SetAcceptKeyFrames(false);//这里就是不接受关键帧

        // Check if there are keyframes in the queue
        // 等待处理的关键帧列表不为空
        if(CheckNewKeyFrames())//检查关键帧
        {
    
    
            // BoW conversion and insertion in Map
            // Step 2 处理列表中的关键帧,包括计算BoW、更新观测、描述子、共视图,插入到地图等
            ProcessNewKeyFrame();//处理新关键帧---更新mappoints 与keyframes的关联、UpdataConnections()


            // Check recent MapPoints
            // Step 3 根据地图点的观测情况剔除质量不好的地图点
            MapPointCulling();  //剔除地图中新添加的但质量不好的MapPoints:
                                //a.IncreaseFound / IncreaseVisible < 25%
                                //b.观测到该点的关键帧太少

            // Triangulate new MapPoints
            // Step 4 当前关键帧与相邻关键帧通过三角化产生新的地图点,使得跟踪更稳
            CreateNewMapPoints();//运动过程中和共视程度比较高的关键帧通过三角化恢复出一些MapPoints---增加的地图点 mlpRecentAddedMapPoints

            // 已经处理完队列中的最后的一个关键帧
            if(!CheckNewKeyFrames())
            {
    
    
                // Find more matches in neighbor keyframes and fuse point duplications
                //  Step 5 检查并融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点
                SearchInNeighbors();
            }

            // 终止BA的标志
            mbAbortBA = false;

            // 已经处理完队列中的最后的一个关键帧,并且闭环检测没有请求停止LocalMapping
            if(!CheckNewKeyFrames() && !stopRequested())
            {
    
    
                // Local BA
                // Step 6 当局部地图中的关键帧大于2个的时候进行局部地图的BA, 和当前关键帧相连的关键帧(应该就是共视程度比较高的关键帧)及MapPoints做局部BA优化
                if(mpMap->KeyFramesInMap()>2)
                    // 注意这里的第二个参数是按地址传递的,当这里的 mbAbortBA 状态发生变化时,能够及时执行/停止BA
                    Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpMap);

                // Check redundant local Keyframes
                // Step 7 检测并剔除当前帧相邻的关键帧中冗余的关键帧
                // 冗余的判定:该相邻关键帧的90%的地图点可以被其它关键帧观测到(说明这个帧是多余的,因为其他的三个以上的帧看到这个关键帧mappoints的90%了 )
                KeyFrameCulling();
            }

            // Step 8 将当前帧加入到闭环检测队列中
            // 注意这里的关键帧被设置成为了bad的情况,这个需要注意
            mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
        }
        else if(Stop())     // 当要终止当前线程的时候
        {
    
    
            // Safe area to stop
            while(isStopped() && !CheckFinish())
            {
    
    
                // 如果还没有结束利索,那么等
                // usleep(3000);
                std::this_thread::sleep_for(std::chrono::milliseconds(3));
            }
            // 然后确定终止了就跳出这个线程的主循环
            if(CheckFinish())
                break;
        }

        // 查看是否有复位线程的请求
        ResetIfRequested();

        // Tracking will see that Local Mapping is not busy
        SetAcceptKeyFrames(true);

        // 如果当前线程已经结束了就跳出主循环
        if(CheckFinish())
            break;

        //usleep(3000);
        std::this_thread::sleep_for(std::chrono::milliseconds(3));

    }

    // 设置线程已经终止
    SetFinish();
}

以下はLocalMapping.cppの全内容です、もしあなたがそれを読むことができれば、それを見てみましょう、それはTracking.cppよりも単純に感じます。
LocalMapping.cpp

おすすめ

転載: blog.csdn.net/joun772/article/details/111294488