ORB-SLAM2源码笔记(3)—— 地图点MapPoint

 ​​​​​​ORB-SLAM2代码详解03: 地图点MapPoint_ncepu_Chen的博客-CSDN博客_orbslam地图点

地图点是三维点,有唯一的id,不同帧的特征点可能对应同一个三维点。

地图点的世界坐标保存在mWorldPos中,它与关键帧的观测关系则保存在mObservations中。其中mObservations是一个key-value结构,key为观测到的某个关键帧,value为当前地图点在该关键帧中的索引,这个索引是该关键帧里面的一个成员变量mvpMapPoints中的索引。mObservations中的nObs记录了当前地图点被多少个关键帧相机观测到了(单目关键帧每次观测算1个相机,双目/RGBD帧每次观测算2个相机)

观测尺度

平均观测距离:mfMinDistance和mfMaxDistance

特征点的观测距离与图像金字塔中的层数线性相关,平均观测距离的上下限由成员变量mfMinDistance和mfMaxDistance表示

  • mfMaxDistance表示若地图点匹配在某特征提取器图像金字塔第7层上的某特征点时的观测距离值
  • mfMinDistance表示若地图点匹配在某特征提取器图像金字塔第0层上的某特征点时的观测距离值

 更新平均观测方向和距离updateNormalAndDepth()

平均观测方向是根据mObservations所有观测到本地图点的关键帧取平均得到的,平均观测距离是根据参考关键帧得到的

  • 构造函数中,创建该地图点的参考帧被设为参考关键帧.

  • 若当前地图点对参考关键帧的观测被删除,则取第一个观测到当前地图点的关键帧做参考关键帧.

void MapPoint::UpdateNormalAndDepth() {
    // step1. 获取地图点相关信息
    map<KeyFrame *, size_t> observations;
    KeyFrame *pRefKF;
    cv::Mat Pos;
    {
        unique_lock<mutex> lock1(mMutexFeatures);
        unique_lock<mutex> lock2(mMutexPos);

        observations = mObservations;
        pRefKF = mpRefKF;            
        Pos = mWorldPos.clone();    
    }

    // step2. 根据观测到当前地图点的关键帧取平均计算平均观测方向
    cv::Mat normal = cv::Mat::zeros(3, 1, CV_32F);
    int n = 0;
    for (KeyFrame *pKF : observations.begin()) {
        normal = normal + normali / cv::norm(mWorldPos - pKF->GetCameraCenter());
        n++;
    }

    // step3. 根据参考帧计算平均观测距离
    cv::Mat PC = Pos - pRefKF->GetCameraCenter();       
    const float dist = cv::norm(PC);                    
    const int level = pRefKF->mvKeysUn[observations[pRefKF]].octave;
    const float levelScaleFactor = pRefKF->mvScaleFactors[level];   
    const int nLevels = pRefKF->mnScaleLevels;                      

    {
        unique_lock<mutex> lock3(mMutexPos);
        mfMaxDistance = dist * levelScaleFactor;
        mfMinDistance = mfMaxDistance / pRefKF->mvScaleFactors[nLevels - 1];
        mNormalVector = normal / n;
    }
}

地图点本身关键帧对该地图点的观测发生变化,就应该调用函数UpdateNormalAndDepth()更新其观测尺度和方向信息. 

地图点的特征描述子

一个地图点对应多个不同关键帧的特征点,所以将地图点的特征描述子定义为所有观测关键帧中描述子的中位数,该描述子与其他所有描述子的中值距离最小

通过比较地图点的描述子和图片特征点的描述子,可以实现3D-2D的匹配。

地图点的删除(先标记,再删除)

地图点的替换(先标记当前地图点,将替换后的地图点叠加,再实际上删除当前地图点)

MapPoint生命周期

创建MapPoint:

1. Tracking初始化

2. Tracking创建新的关键帧,新关键帧会带来新的地图点

3. Tracking恒速跟踪模型中产生临时地图点,仅用于跟踪,不进入地图。

4. LocalMapping中将当前关键帧与前一关键帧基尼下嗯匹配,生成新的地图点。

删除MapPoint:

1. LocalMapping中删除坏点

2. 当地图点对关键帧的观测少于2个,无法三角化,删除

替换MapPoint:

LoopClosing闭环矫正

猜你喜欢

转载自blog.csdn.net/luoyihao123456/article/details/125164679