前言
地图点在投影匹配时只能对应一个特征描述子,选择具有代表性的描述子是必要的。
1.函数声明
/*
由于一个地图点会被许多相机观测到,因此在插入关键帧后,需要判断是否更新代表当前点的描述子
先获得当前点的所有描述子,然后计算描述子之间的两两距离,最好的描述子与其他描述子应该具有最小的距离
中值*/
void MapPoint::ComputeDistinctiveDescriptors()
{
....
}
2.函数定义
1.获取地图点的所有观测关键帧的信息。
// Retrieve all observed descriptors
vector<cv::Mat> vDescriptors;
map<KeyFrame*,size_t> observations;
{
unique_lock<mutex> lock1(mMutexFeatures);
if(mbBad)
return;
observations=mObservations;
}
if(observations.empty())
return;
vDescriptors.reserve(observations.size());
2.遍历观察到该点的关键帧,把其对应的特征描述子放在一个向量中。
for(map<KeyFrame*,size_t>::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;
3.计算描述子之间的距离
const size_t N = vDescriptors.size();
// 将Distances表述成一个对称的矩阵
// float Distances[N][N];
std::vector<std::vector<float> > Distances;
Distances.resize(N, vector<float>(N, 0));
for (size_t i = 0; i<N; i++)
{
// 和自己的距离当然是0
Distances[i][i]=0;
// 计算并记录不同描述子距离
for(size_t j=i+1;j<N;j++)
{
int distij = ORBmatcher::DescriptorDistance(vDescriptors[i],vDescriptors[j]);
Distances[i][j]=distij;
Distances[j][i]=distij;
}
}
4.选择最具有代表性的描述子
int BestMedian = INT_MAX; // 记录最小的中值
int BestIdx = 0; // 最小中值对应的索引
for(size_t i=0;i<N;i++)
{
// 第i个描述子到其它所有描述子之间的距离
// vector<int> vDists(Distances[i],Distances[i]+N);
vector<int> vDists(Distances[i].begin(), Distances[i].end());
sort(vDists.begin(), vDists.end());
// 获得中值
int median = vDists[0.5*(N-1)];
// 寻找最小的中值
if(median<BestMedian)
{
BestMedian = median;
BestIdx = i;
}
}
{
unique_lock<mutex> lock(mMutexFeatures);
mDescriptor = vDescriptors[BestIdx].clone();
}
}
结束语
以上就是我学习到的内容,如果对您有帮助请多多支持我,如果哪里有问题欢迎大家在评论区积极讨论,我看到会及时回复。
标签:Distances,关键帧,cc,MapPoint,vDescriptors,源码,observations,mit,描述 From: https://blog.csdn.net/2301_76831056/article/details/143646473