目录
3.3 通过Sim变换,寻找 pKF1 中特征点和 pKF2 中的新的匹配
3.4 通过Sim变换,寻找 pKF2 中特征点和 pKF1 中的新的匹配
3.5 一致性检查,只有在两次互相匹配中都出现才能够认为是可靠的匹配
1.函数作用
通过Sim3变换,搜索两个关键帧中更多的匹配点对。
图像下方的蓝线是我们先前通过SearchByBoW函数预先粗匹配的特征点。
我们在SearchBySim3函数中要做的是对两帧特征点进行进一步匹配。寻找 pKF1 中特征点和 pKF2 中的新的匹配、寻找 pKF2 中特征点和 pKF1 中的新的匹配。
2.函数流程
Step 1: 准备工作:内参,计算Sim3的逆
Step 2:记录已经匹配的特征点
Step 3:通过Sim变换,寻找 pKF1 中特征点和 pKF2 中的新的匹配
Step 4:通过Sim变换,寻找 pKF2 中特征点和 pKF1 中的新的匹配
Step 5: 一致性检查,只有在两次互相匹配中都出现才能够认为是可靠的匹配
3.函数解析
3.1 准备工作:内参,计算Sim3的逆
函数传入的参数为:第一帧pKF1、第二帧pKF2、两帧的匹配关系vpMatches12、sim3的尺度因子s12,第一帧到第二帧的变换R12、t12、重投影阈值th。
在准备阶段,获取相机的内参fx、fy、cx、cy。
获取从world到camera1的变换:R1w、t1w。
获取从world到camera2的变换:R2w、t2w。
关于sim3变换,我们回忆相机的知识:将世界坐标系坐标投影到像素坐标系坐标是这样的:
我们求出Sim3 的逆:sR12、sR21、t21。
取出关键帧的地图点存放在向量vpMapPoints1、vpMapPoints2中并统计它们的数量,分别存放在变量N1、N2中。
用bool型向量vbAlreadyMatched1、vbAlreadyMatched2记录pKF1,pKF2中已经匹配的特征点,已经匹配记为true,否则false。
3.2 记录已经匹配的特征点
我们遍历变量vpMatches12,其中记录着帧1pKF1到帧2pKF2的匹配信息,具体来说:就是如果vpMatches12[3]=5,就意味着第一帧pKF1中的索引为4的特征点和第二帧pKF2的索引为6的特征点匹配成功。
如果有匹配成功的,记录pKF1中第i个特征点已经匹配成功,vbAlreadyMatched1[i]=true,同时得到该地图点在关键帧pkF2 中的id,记录pKF2中第idx2个特征点在pKF1中有匹配,即vbAlreadyMatched2[idx2]=true;。
通过这一步,我们填充了vbAlreadyMatched1、vbAlreadyMatched2,即标注了匹配信息。
3.3 通过Sim变换,寻找 pKF1 中特征点和 pKF2 中的新的匹配
遍历帧pKF1中每一个特征点:
若该特征点存在对应的地图点或者该特征点已经有匹配点了,跳过。
地图点是要删掉的,跳过。
通过Sim变换,将pKF1的地图点投影到pKF2中的图像坐标p3Dc2。深度值为负,跳过。投影到camera2图像坐标 (u,v),判断投影点是否在图像范围内,否则跳过。检测深度值在有效范围内,否则跳过。
搜索在该区域内的所有候选匹配特征点记录在vIndices里,vIndices存储着帧二中的特征点的索引,该函数的具体解析如下:
ORB-SLAM2 ---- Frame::GetFeaturesInArea函数解析
https://blog.csdn.net/qq_41694024/article/details/128227154 取出帧一pKF1中关于该特征点的描述子,和帧二pKF2中所有待匹配特征点索引vIndices取出特征点进行描述子的汉明距离计算。选出汉明距离最小的(匹配关系最好的)记录最佳匹配的索引bestIdx和最佳汉明距离bestDist,若最佳汉明距离小于我们的阈值TH_HIGH,则认为匹配有效,记录匹配信息vnMatch1[i1]=bestIdx;。
3.4 通过Sim变换,寻找 pKF2 中特征点和 pKF1 中的新的匹配
同3.3。
匹配信息记录在vnMatch2中。
3.5 一致性检查,只有在两次互相匹配中都出现才能够认为是可靠的匹配
我们进行帧一pKF1到帧二pKF2的重投影匹配,又进行了帧二pFK2到帧一pKF1的重投影匹配,将投影信息记录在了vnMatch1和vnMatch2中。
一致性检查的目的是检测我们在第一帧投影到第二帧中的信息是否能在第二帧投影到第一帧的信息对上。
如果对上了,我们更新两帧的匹配关系vpMatches12,返回成功匹配的数量nFound。