这两个算法相似,都是为了获取局部特征点的特征向量的。具体数学原理不过多赘述
值得注意的是这两个函数在早期版本(opencv3.4 以前)中属于cv2.xfeatures2d
, 而在4以后是可以直接省掉xfeatures2d
的。
算法基础
代码如下
import cv2
import numpy as np
img = cv2.imread('cat.png')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转成gray计算更快
s = cv2.xfeatures2d.SIFT_create()
# s = cv2.xfeatures2d.SURF_create()
kp = s.detect(gray,None)#找到关键点
kp, des = s.detectAndCompute(gray, None) #找到关键点并且返回每个点的特征向量
kp, des = s.compute(gray, kp)
img=cv2.drawKeypoints(img.copy(),kp,img.copy())#绘制关键点
cv2.imshow('sp',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
画出来的图大概就是这样子
sift和surf算法的调用方式也类似,一个是SIFT_create(), 一个是SURF_create()
重要的三个函数
kp = s.detect(gray,None)#找到关键点
kp, des = s.detectAndCompute(gray, None) #找到关键点并且返回每个点的特征向量
kp, des = s.compute(gray, kp)
如果只想要kp点,就只用detect即可,既要kp也要特征向量就用detectAndCompute,用了detect之后,又想查看特征向量,就用compute()
通过构造特征描述子,就可以实现特征匹配
特征匹配
先通过图像金字塔创建一张更大的图片
img2 = cv2.pyrUp(img)
gray2= cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
kp2, des2 = sift.detectAndCompute(gray2, None)
再使用同样的方式,用SIFT获取相应的特征点
img2 = cv2.pyrUp(img)
gray2= cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
kp2, des2 = s.detectAndCompute(gray2, None)
然后使用暴力匹配(Brute-Force) BFMatcher
bf = cv2.BFMatcher(crossCheck=True)
matches = bf.match(des, des2)
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv2.drawMatches(img, kp, img2, kp2, matches[:10], None, flags=2)
cv2.imshow('match',img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
先学到这吧,不说了,周末嗨皮去了