ORB-SLAM2 --- MapPoint::ComputeDistinctiveDescriptors 函数

目录

一、函数作用

二、函数步骤 

三、code 

四、函数解析 


一、函数作用

        计算地图点最具代表性的描述子。

        由于一个地图点会被许多相机观测到,因此在插入关键帧后,需要判断是否更新代表当前点的描述子,先获得当前点的所有描述子,然后计算描述子之间的两两距离,最好的描述子与其他描述子应该具有最小的距离中值。

二、函数步骤 

Step 1 获取该地图点所有有效的观测关键帧信息

Step 2 遍历观测到该地图点的所有关键帧,对应的orb描述子,放到向量vDescriptors中

Step 3 计算这些描述子两两之间的距离.

Step 4 选择最有代表性的描述子,它与其他描述子应该具有最小的距离中值

三、code 

void MapPoint::ComputeDistinctiveDescriptors()
{
    // Retrieve all observed descriptors
    vector vDescriptors;

    map observations;

    // Step 1 获取该地图点所有有效的观测关键帧信息
    {
        unique_lock lock1(mMutexFeatures);
        if(mbBad)
            return;
        observations=mObservations;
    }

    if(observations.empty())
        return;

    vDescriptors.reserve(observations.size());

    // Step 2 遍历观测到该地图点的所有关键帧,对应的orb描述子,放到向量vDescriptors中
    for(map::iterator mit=observations.begin(), mend=observations.end(); mit!=mend; mit++)
    {
        // mit->first取观测到该地图点的关键帧
        // mit->second取该地图点在关键帧中的索引
        KeyFrame* pKF = mit->first;

        if(!pKF->isBad())        
            // 取对应的描述子向量                                               
            vDescriptors.push_back(pKF->mDescriptors.row(mit->second));     
    }

    if(vDescriptors.empty())
        return;

    // Compute distances between them
    // Step 3 计算这些描述子两两之间的距离
    // N表示为一共多少个描述子
    const size_t N = vDescriptors.size();
	
    // 将Distances表述成一个对称的矩阵
    // float Distances[N][N];
	std::vector > Distances;
	Distances.resize(N, vector(N, 0));
	for (size_t i = 0; i vDists(Distances[i],Distances[i]+N);
		vector vDists(Distances[i].begin(), Distances[i].end());
		sort(vDists.begin(), vDists.end());

        // 获得中值
        int median = vDists[0.5*(N-1)];
        
        // 寻找最小的中值
        if(median lock(mMutexFeatures);
        mDescriptor = vDescriptors[BestIdx].clone();       
    }
}

四、函数解析 

        判断该地图点是否是bad地图点,若不是则获取这个地图点的所有观测信息用临时变量observations保存,它是个map类型的变量。

        存储的该地图点可以被哪些关键帧KeyFrame观测到,在这些关键帧中的索引size_t是多少。

        遍历观测到该地图点的所有关键帧observations,对应的orb描述子,放到向量vDescriptors中。

        计算这些描述子的两两距离存储到矩阵Distances中。

        假设这里的矩阵是4*4的。

\begin{bmatrix} a_{11} & a_{12} &a_{13} &a_{14} \\ a_{21} & a_{22}& a_{23}&a_{24} \\ a_{31}& a_{32}& a_{33} &a_{34} \\ a_{41}& a_{42}& a_{43}& a_{44} \end{bmatrix}

         即观测到该地图点的帧有4个,取出它们四个的描述子,a_{11}=a_{22}=a_{33}=a_{44}=0,即第一个描述子和第一个描述子的距离为0(自己和自己比较当然为0),a_{12}=a_{21},它们的数值等于第一个描述子和第二个描述子的汉明距离。

        我们有了描述子矩阵后,我们遍历每一行描述子矩阵,寻找每一行的距离中值,拿第一行来说,a_{11} ~a_{12} ~a_{13} ~a_{14}的中位数,遍历所有行,找到最小行的中位数以及它的行索引。

        将这个地图点最具代表性的描述子设置为最小的行的中位数索引对应的描述子。

        

你可能感兴趣的:(orb-slam2,c++,算法,slam)