日更 SLAM 一边理论一边实践第 4 天—过滤特征(4)
前言
将相邻 2 帧图像上特征点提取并进行匹配,接下来就是匹配特征点过滤掉那些误匹配特征点。尝试用两种方法来消除误匹配的关键点。
将会了解哪些内容
- BFMatcher 关键匹配器使用方法
- 误匹配的原因
- 过滤掉误匹配的方法,交叉验证和 Ratio test
特征点匹配
matches = None
if self.last is not None:
matches = self.bf.match(des,self.last['des'])
matches = zip([kps[m.queryIdx] for m in matches],[self.last['kps'][m.trainIdx] for m in matches])
# update last
self.last = {'kps':kps,'des':des}
# return kps,des,matches
return matches
Brute Force Matcher
其实我们只关心那些匹配上点,对于没有匹配的关键点我们其实并不关心。现在我们来简单看一下 BFMatcher 的 API 其返回值的格式如何,返回数据结构为 DMatch 列表的数据结构
- distance: 表示描述符(descriptors) 之间距离,距离小表示两个值越接近
- trianIdx: 表示在训练集(对应于代码中
des
)描述符(descriptors)的索引 - qureyIdx: 表示搜索数据(对应于
self.last['des']
- imgIdx: 训练图像索引
trianIdx 和 queryIdx 分别是 2 组关键点的索引,queryIdx 索引到第一组关键点,而 trainidx 索引到第二组关键点
绘制特征点
通过 opencv 提供 circle 来绘制特征点,然后用 line 连接前后帧的匹配关键点
for pt1,pt2 in matches:
# print(pt1)
u1,v1 = map(lambda x:int(round(x)),pt1.pt)
u2,v2 = map(lambda x:int(round(x)),pt2.pt)
cv2.circle(img,(u1,v1),3,(0,255,0))
cv2.line(img,(u1,v1),(u2,v2),color=(255,0,0))
从上图来看存在许多误匹配点
误匹配的原因
- FP 将非匹配特征点检测为匹配,对于这样误判为匹配特征点,是可以通过优化将其提出
- FN 为检测出的特征点,对于这种类型是因为 Match 算法没有检测出来,所以无法优化
优化误匹配
匹配距离衡量方法换成 cv2.NORM_HAMMING
,然后BFMatcher
的 crossCheck=True
,也就是开启交叉验证。匹配条件就会更加严格,只有到 A 关键点集合中的第 i 个特征点与 B 关键点集合中的第 j 个特征点距离最近,并且 B 关键点集合中的第 j 个特征点到 A 关键点集合中的第 i 个特征点也是最近时才会返回最佳匹配(i,j),这就是所谓交叉验证
self.bf = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
简单总结一下
- goodFeaturesToTrack 提取特征点
- 用这些提取特征点(ORB)来计算 descriptor 关键点的描述符
- 用 BFMatcher 来基于关键点的描述符来对邻近两 frame 匹配关键点
简单调整了 BFMatcher ,采用对匹配点按距离进行过滤,只有满足条件
self.bf = cv2.BFMatcher(cv2.NORM_HAMMING)
ret = []
if self.last is not None:
matches = self.bf.knnMatch(des,self.last['des'],k=2)
for m,n in matches:
if m.distance < 0.75*n.distance:
ret.append((kps[m.queryIdx],self.last['kps'][m.trainIdx]))
# update last
self.last = {'kps':kps,'des':des}
# return kps,des,matches
return ret
- knnMatch 方法中
k=2
表示每个 match 得到两个最接近的描述子(descriptor),然后计算最接近距离和次接近距离的比值,当比值大于既定值,才作为最终 match 的一对关键点
随后为了提升匹配的精度,可以采用随机样本一致性(RANSAC)方法,这个将在下一次分享展开来介绍。
转载自:https://juejin.cn/post/7126125280871055367