ORB-SLAM代码详解之SLAM.TrackMonocular

转载请注明出处:http://blog.csdn.net/c602273091/article/details/54955663

总述

在mono_kitti.cc中运行kitti数据集的时候,初始化完了system之后,就出现了并行的多个线程:追踪、局部地图构建、闭环检测、地图显示等等。这个时候我们就需要喂入数据给整个系统,所以就是:

SLAM.TrackMonocular(im,tframe);

把传感器采集的图片以及时间戳传入,我们就可以更新系统的状态,获取新的数据,更新地图。

这个时候TrackMonocular的流程图为:
这里写图片描述

TrackMonocular

对TrackMonocular进行解释,具体如下:

cv::Mat System::TrackMonocular(const cv::Mat &im, const double &timestamp)
{
    // 传感器不是单目摄像头、退出
    if(mSensor!=MONOCULAR)
    {
        cerr << "ERROR: you called TrackMonocular but input sensor was not set to Monocular." << endl;
        exit(-1);
    }

    // Check mode change
    // 这一部分主要是对局部地图线程进行操作.
    // mbActivateLocalizationMode是是否停止局部地图线程
    // mbDeactivateLocalizationMode是是否清空局部地图.
    {
        // 独占锁,主要是为了mbActivateLocalizationMode和mbDeactivateLocalizationMode
        // 不会发生混乱,没有死锁或者在临界区
        unique_lock<mutex> lock(mMutexMode);
        // mbActivateLocalizationMode为true会关闭局部地图线程
        if(mbActivateLocalizationMode)
        {
            mpLocalMapper->RequestStop();
            // 设置local map的mbStopRequested,mbAbortBA为true.
            // 当这两个为true的时候,那么进行就会去关闭局部地图的线程

            // Wait until Local Mapping has effectively stopped
            // mbStopped为true,说明局部地图线程已经关闭了
            while(!mpLocalMapper->isStopped())
            {
                usleep(1000);
            }
            // 局部地图关闭以后,只进行追踪的线程
            // 只计算相机的位姿,没有对局部地图进行更新
            // 设置mbOnlyTracking为真
            mpTracker->InformOnlyTracking(true);
            // 执行完当前的部分之和把mbActivateLocalizationMode再置回false.
            // 当然这里设置mbActivateLocalizationMode为true的部分应该是没有新的关键帧和点云的时候
            // 关闭线程可以使得别的线程得到更多的资源
            mbActivateLocalizationMode = false;
        }
        // 如果mbDeactivateLocalizationMode是true
        // 设置mbActivateLocalizationMode为false
        // 局部地图线程就被释放, 关键帧从局部地图中删除.
        // mbStopped和mbStopRequested被置为false.
        if(mbDeactivateLocalizationMode)
        {
            mpTracker->InformOnlyTracking(false);
            mpLocalMapper->Release();
            mbDeactivateLocalizationMode = false;
        }
    }

    // Check reset
    // 检查是否需要进行复位重置.
    {
        // 给mbReset加锁,防止被别的线程修改
        unique_lock<mutex> lock(mMutexReset);
        if(mbReset)
        {
            // mpViwer暂停,视图停止更新
            // 局部地图:mpLocalMapper和闭环检测:mpLoopClosing被停止.
            // Bow:mpKeyFrameDB和mpMap被清空
            // 就是把所有资源释放
            mpTracker->Reset();
            mbReset = false;
        }
    }
    // 可以看出上面这两部分都是对于各个线程状态的反馈.
    // 其实可以看做是对上一个状态的反馈.
    // 接下来的部分才是最重要的部分,获取数据,对各个线程的数据进行更新, 对地图重新进行计算.
    return mpTracker->GrabImageMonocular(im,timestamp);
}

mpTracker->GrabImageMonocular

这部分是上一部分的核心。对GrabImageMonocular的解释如下:

cv::Mat Tracking::GrabImageMonocular(const cv::Mat &im, const double &timestamp)
{
    // 把输入的图片设为当前帧.
    mImGray = im;

    // 若图片是三\四通道的,还需要转化为灰度图.
    if(mImGray.channels()==3)
    {
        if(mbRGB)
            cvtColor(mImGray,mImGray,CV_RGB2GRAY);
        else
            cvtColor(mImGray,mImGray,CV_BGR2GRAY);
    }
    else if(mImGray.channels()==4)
    {
        if(mbRGB)
            cvtColor(mImGray,mImGray,CV_RGBA2GRAY);
        else
            cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
    }

    // 若状态是未初始化或者当前获取的图片是第一帧的时候,那么就需要进行初始化.
    // 传入的参数就是当前帧(灰度图)、时间戳、ORBextractor(ORB特征)、DBoW2的字典、标定矩阵、畸变参数、立体视觉的(baseline)x(fx)、可靠点的距离的阈值
    // mCurrentFrame就是对当前帧进行处理. 获取ORB特征、获取尺度信息.
    // 这里需要进行更加深入的研究.
    if(mState==NOT_INITIALIZED || mState==NO_IMAGES_YET)
        mCurrentFrame = Frame(mImGray,timestamp,mpIniORBextractor,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);
    else
        mCurrentFrame = Frame(mImGray,timestamp,mpORBextractorLeft,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);

    // 追踪,初始化以及特征匹配.
    // 这里需要更加深入的研究.
    Track();

    // mTcw是位姿  
    // clone是cv::Mat特有的方法.
    // 实现的就是完全拷贝, 把数据完全拷贝而不共享数据.
    return mCurrentFrame.mTcw.clone();
}

Frame

对于这一部分,需要特别研究一下:

// 若状态是未初始化或者当前获取的图片是第一帧的时候,那么就需要进行初始化.
// 传入的参数就是当前帧(灰度图)、时间戳、ORBextractor(ORB特征)、DBoW2的字典、标定矩阵、畸变参数、立体视觉的(baseline)x(fx)、可靠点的距离的阈值
// mCurrentFrame就是对当前帧进行处理. 获取ORB特征、获取尺度信息.
// 这里需要进行更加深入的研究.
if(mState==NOT_INITIALIZED || mState==NO_IMAGES_YET)
        mCurrentFrame = Frame(mImGray,timestamp,mpIniORBextractor,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);
    else
        mCurrentFrame = Frame(mImGray,timestamp,mpORBextractorLeft,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth);

这里写图片描述

整个Frame的流程图如上所示,比较清晰。

对Frame部分进行注释得到:

Frame::Frame(
  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值