1、match
# 初始化 BFMatcher
bf = cv.BFMatcher()
# 对描述子进行匹配
# des1/des2分别是两幅图片特征点的特征向量
matches = bf.match(des1, des2)
# 打印match返回数据的类型
print(type(matches[0]))
match匹配的返回结果是DMatch类型。
DMatch数据结构包含三个非常重要的数据分别是queryIdx,trainIdx,distance; queryIdx:某一特征点在本帧图像的索引; trainIdx:trainIdx是该特征点在另一张图像中相匹配的特征点的索引; distance:代表这一对匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。
print("queryIdx=%d"%matches[0].queryIdx)
print("trainIdx=%d"%matches[0].trainIdx)
print("distance=%d"%matches[0].distance)
输出:
queryIdx=0
trainIdx=105
distance=68
?2、Knnmatch
bf = cv2.BFMatcher()
matches1 = bf.knnMatch(des1, des2, k=2)
# 打印match返回数据的类型
print(type(matches1[0]))
<class 'tuple'>
knnMatch匹配的返回结果是一个元组:说明结果不能改变;
对元组内元素进行类型查询:?所以Knnmatch与match的返回值类型一样,只不过一组返回的2个DMatch类型。
bf = cv2.BFMatcher()
matches1 = bf.knnMatch(des1, des2, k=2)
for x in matches1[0]:
print(type(x))
3、总结?
综上所知:
(1)match匹配的返回结果是DMatch类型。distance:代表这一对匹配的特征点描述符的欧式距离,数值越小也就说明俩个特征点越相近。
(2)Knnmatch与match的返回值类型一样,只不过一组返回的2个DMatch类型。这2个DMatch数据类型是2个与原图像特征点最接近的2个特征点(match返回的是最匹配的),只有这2个特征点的欧式距离小于一定值的时候才会认为匹配成功。(可以理解为:2个与原图像特征点最接近和次接近的特征点,一般第一个是最接近匹配点,第二个是次接近匹配点)
4、匹配优化?
(1)对于match类型(注意显示匹配结果:cv.drawMatches)
# 初始化 BFMatcher
bf = cv.BFMatcher()
# 对描述子进行匹配
# des1/des2分别是两幅图片特征点的特征向量
matches = bf.match(des1, des2)
# 计算最大距离和最小距离
min_distance = matches[0].distance
max_distance = matches[0].distance
for x in matches:
if x.distance < min_distance:
min_distance = x.distance
if x.distance > max_distance:
max_distance = x.distance
# 筛选匹配点
'''
当描述子之间的距离大于两倍的最小距离时,认为匹配有误。
但有时候最小距离会非常小,所以设置一个经验值30作为下限。
'''
good_match = []
for x in matches:
if x.distance <= max(2 * min_distance, 30):
good_match.append(x)
# 绘制匹配结果
outimage = cv.drawMatches(img1, kp1, img2, kp2, match, outImg=None)
(2)对于Knnmatch类型(注意显示匹配结果:cv.drawMatchesKnn)
# 调整ratio
# ratio=0.4:对于准确度要求高的匹配;
# ratio=0.6:对于匹配点数目要求比较多的匹配;
# ratio=0.5:一般情况下。
ratio1 = 0.3
good1 = []
for m1, n1 in matches1:
# 如果最接近和次接近的比值小于一个既定的值,那么我们保留这个最接近的值,认为它和其匹配的点为good_match
if m1.distance < ratio1 * n1.distance:
good1.append([m1])
match_result1 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good1, None, flags=2)
|