网上已经有很多关于SIFT算法的教程了,本篇主要讲应用,毕竟我是做应用的嘛。
本篇教程使用opencv版本为4.5.1。
这是opencv官网使用SIFT的示例代码:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # queryImage
img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # trainImage
# Initiate SIFT detector
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# BFMatcher with default params
bf = cv.BFMatcher()
matches = bf.knnMatch(des1,des2,k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append([m])
# cv.drawMatchesKnn expects list of lists as matches.
img3 = cv.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
plt.imshow(img3),plt.show()
这是我自己修改过后可以得出x,y的版本。
import cv2 as cv
dir1 = 'C:\\Users\\luwei\\Desktop\\01.png'
dir2 = 'C:\\Users\\luwei\\Desktop\\02.png'
print(dir1)
print(dir2)
img1 = cv.imread(dir1,cv.IMREAD_GRAYSCALE) # queryImage
img2 = cv.imread(dir2,cv.IMREAD_GRAYSCALE) # trainImage
# Initiate SIFT detector
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# BFMatcher with default params
bf = cv.BFMatcher()
matches = bf.knnMatch(des1,des2,k=2)
#寻找匹配最好的点,并记录其标识
kp1idx = []
for m,n in matches:
if m.distance < 0.1*n.distance:
kp1idx.append(m.queryIdx)
#获取所有关键点的位置
kp1pos = cv.KeyPoint_convert(kp1)
#获取小图在大图中的x和y值
x = 0
y = 0
for idx in kp1idx:
x = kp1pos[idx][0] + x
y = kp1pos[idx][1] + y
x = x / len(kp1idx)
y = y / len(kp1idx)
#转换为整数
x = int(x)
y = int(y)
#输出
img3 = img1.copy()
cv.circle(img3,(x,y),5,(0,0,255))
cv.imwrite('C:\\Users\\luwei\\Desktop\\03.png', img3)
稍加改造就成一个函数了
import cv2 as cv
def GetPic(BigImg,SmallImg):
# Initiate SIFT detector
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(BigImg,None)
kp2, des2 = sift.detectAndCompute(SmallImg,None)
# BFMatcher with default params
bf = cv.BFMatcher()
matches = bf.knnMatch(des1,des2,k=2)
#寻找匹配最好的点,并记录其标识
kp1idx = []
for m,n in matches:
if m.distance < 0.1*n.distance:
kp1idx.append(m.queryIdx)
#获取所有关键点的位置
kp1pos = cv.KeyPoint_convert(kp1)
#获取小图在大图中的x和y值
x = 0
y = 0
for idx in kp1idx:
x = kp1pos[idx][0] + x
y = kp1pos[idx][1] + y
x = x / len(kp1idx)
y = y / len(kp1idx)
#转换为整数
x = int(x)
y = int(y)
#返回x,y
return x,y