使用SIFT定位图像之间的对应关系

时间:2018-05-27 08:06:35

标签: python opencv sift


我有一个512x512的图像,它提供了6109个SIFT关键点。 现在,我旋转了它,然后我得到了6070个SIFT关键点。

我试过了

import cv2
import numpy as np
np.set_printoptions(threshold=np.nan)
img = cv2.imread('home.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
kp,des = sift.detectAndCompute(gray,None)
print('kp',len(kp))
print('des',des.shape)
for i in range(len(kp)):
    print('x ',kp[i].pt[0])
    print('y ',kp[i].pt[1])
    print('size',kp[i].size)
    print('response',kp[i].response)
    print('descriptor',np.sort(des[i]))
    print('\n')

将输出发送到文本文件 现在我对旋转的图像做了同样的事情 你必须注意到我在将128值描述符写入文件之前对其进行排序,这样如果值的顺序在描述符中发生变化,那么在轮换时它仍会匹配。

我的结论是,在12179个描述符(6070 + 6109)中,只有两个是相同的。休息至少差异一个数字,通常是我看到的许多人 你能建议一个python代码,它会显示两个图像之间对应关系的x,y坐标吗? 此外,在比较描述符时,我必须在这里做一些根本性的错误。请指出。
感谢

2 个答案:

答案 0 :(得分:2)

  1. 为什么要对描述符进行排序? 128维描述符是描述特征关键点的东西(顾名思义)。通过排序,您基本上会丢失关键点/功能的描述。
  2. 搜索相同的描述符不是查找对应关系的好方法。你必须找到具有最小欧氏距离(或一些其他距离测量)的描述符,以获得对应关系。在opencv中有许多算法,如Brute force match或基于knn的匹配器或基于flann的匹配器。你必须将描述符作为输入给这些匹配器(不要通过排序或其他操作修改你的decsriptor值) 例如

    kp1, des1 = sift.detectAndCompute(img1,None)
    kp2, des2 = sift.detectAndCompute(img2,None)
    
    # BFMatcher with default params
    bf = cv2.BFMatcher()
    matches = bf.knnMatch(des1,des2, k=2)
    
  3. 匹配将具有对应的索引和这些对应之间的距离

    您可以根据matches.distance对此匹配进行排序 并使用matches.queryIdx和matches.trainIdx

    获取x和y坐标

    你可以使用kp1获取x和y位置[匹配[idx] .trainIdx]和kp2 [匹配[idx] .queryIdx]

答案 1 :(得分:1)

这是Garvita Tiwari提供的细节的实施 我使用的是带有opencv 3.4.1的python 2.7.12

import cv2
import numpy as np
src_img = cv2.imread('src.jpg')
test_img = cv2.imread('test.jpg')
src_gray= cv2.cvtColor(src_img,cv2.COLOR_BGR2GRAY)
test_gray= cv2.cvtColor(test_img,cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
src_kp,src_desc = sift.detectAndCompute(src_gray,None)
test_kp,test_desc = sift.detectAndCompute(test_gray,None)
bf = cv2.BFMatcher()
matches = bf.knnMatch(src_desc,test_desc, k=2)
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])
print 'so the correspondences are'
for i in range(len(good)):
    print int(src_kp[good[i][0].queryIdx].pt[0]),int(src_kp[good[i][0].queryIdx].pt[1]) ,'->',int(test_kp[good[i][0].trainIdx].pt[0]) ,int(test_kp[good[i][0].trainIdx].pt[1])