opencv图像特征值特征匹配

1.蛮力匹配

首先在第一幅图像中选取一个关键点,然后依次与第二幅图像的每个关键点进行(描述符)距离测试,最后返回距离最近的关键点。

(1)对ORB 描述符进行蛮力匹配

代码速记:

  • cv2.ORB_create()
  • orb.detectAndCompute()
  • cv2.BFMatcher()
  • bf.match()
  • sorted()
  • cv2.drawMatches()

参数解释:

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
  • normType:它是用来指定要使用的距离测试类型。默认值为cv2.Norm_L2。这很适合SIFT 和SURF 等(c2.NORM_L1 也可以)。对于使用二进制描述符的ORB,BRIEF,BRISK算法等,要使用cv2.NORM_HAMMING,这样就会返回两个测试对象之间的汉明距离。如果ORB 算法的参数设置为V TA_K==3 或4,normType就应该设置成cv2.NORM_HAMMING2。
  • crossCheck:默认值为False。如果设置为True,匹配条件就会更加严格,只有到A 中的第i 个特征点与B 中的第j 个特征点距离最近,并且B 中的第j 个特征点到A 中的第i 个特征点也是最近(A 中没有其他点到j 的距离更近)时才会返回最佳匹配(i,j)。也就是这两个特征点要互相匹配才行。这样就能提供统一的结果,这可以用来替代D.Lowe在SIFT 文章中提出的比值测试方法。
matches = bf.match(des1, des2)#返回最佳匹配

matches = bf.knnMatch(des1, des2, k=2)
#每个关键点返回k 个最佳匹配(降序排列之后取前k 个),其中k 是由用户设定的。
#如果除了匹配之外还要做其他事情的话可能会用上(比如进行比值测试)。

bf:match(des1,des2)返回值是一个DMatch 对象列表。这个DMatch 对象具有下列属性:

  • DMatch.distance:描述符之间的距离。越小越好。
  • DMatch.trainIdx:目标图像中描述符的索引。
  • DMatch.queryIdx:查询图像中描述符的索引。
  • DMatch.imgIdx:目标图像的索引。
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)  # 前10个匹配

img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)

用来绘制匹配的点。它会将这两幅图像先水平排列,然后在最佳匹配的点之间绘制直线(从原图像到目标图像)。如果前面使用的是BFMatcher.knnMatch(),现在我们可以使用函数cv2.drawMatchsKnn为每个关键点和它的k 个最佳匹配点绘制匹配线。如果k 等于2,就会为每个关键点绘制两条最佳匹配直线。如果我们要选择性绘制话就要给函数传入一个掩模。

实战:

我们有一个查询图像和一个目标图像。我们要使用特征匹配的方法在目标图像中寻找查询图像的位置。

def bf_orb(self):
    img1 = cv2.imread('../images/box.png', 0)  # queryImage
    img2 = cv2.imread('../images/box_in_scene.png', 0)  # trainImage
    #【1】初始ORB特征检测器
    orb = cv2.ORB_create()
    #【2】用ORB找到两幅图像的关键点和描述符
    kp1, des1 = orb.detectAndCompute(img1, None)
    kp2, des2 = orb.detectAndCompute(img2, None)
    #【3】创建BFMatcher对象
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    #【4】匹配两幅图像的描述符
    matches = bf.match(des1, des2)
    #【5】根据描述符之间的距离来排序
    matches = sorted(matches, key=lambda x: x.distance)
    #【6】画出前10匹配的特征点
    img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None,
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值