得到特征关键点,并可以将关键点向量化.
实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。
SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。
SIFT
尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。
尺度空间
对现实中物体的描述一定要在一个十分重要的前提下进行,这个前提就是对自然界建模时的尺度。当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体的尺度,因此我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。图像的尺度空间表达指的是图像的所有尺度下的描述。
1.尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
2.关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
3.方向确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
4.关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。
这个算法是受专利保护的。所以这个算法包含在 OpenCV 中的收费模块中。因此我们降低版本才可能用,本来我的Opencv是4.2.x版本,是用不了SIFT算法的。因此首先uninstall它,再pip install相应版本的opencv-python和opencv-contrib-python。【SIFT在这个包里】
步骤:
1.卸载现有的高版本:pip uninstall opencv-python
2.安装3.4.2.16版本的,版本要一致哦。亲测可用!
pip install opencv-python==3.4.2.16
pip install opencv-contrib-python==3.4.2.16
sift_kp(image):进行sift关键点检测
get_good_match(des1, des2):对两张图进行最佳匹配
显示出所有较好的匹配和前N个较好的关键点匹配。
import cv2
import numpy as np
def sift_kp(image):
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
kp, des = sift.detectAndCompute(image, None)
kp_image = cv2.drawKeypoints(gray_image, kp, None)
return kp_image, kp, des
def get_good_match(des1, des2):
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2) # des1为模板图,des2为匹配图
matches = sorted(matches, key=lambda x: x[0].distance / x[1].distance)
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append(m)
return good
img1 = cv2.imread(r'd:/t1.jpg')
img2 = cv2.imread(r'd:/t2.jpg')
kpimg1, kp1, des1 = sift_kp(img1)
kpimg2, kp2, des2 = sift_kp(img2)
cvshow('img1',np.hstack((img1,kpimg1)))
cvshow('img2',np.hstack((img2,kpimg2)))
goodMatch = get_good_match(des1, des2)
all_goodmatch_img= cv2.drawMatches(img1, kp1, img2, kp2, goodMatch, None, flags=2)
# goodmatch_img自己设置前多少个goodMatch[:10]
goodmatch_img = cv2.drawMatches(img1, kp1, img2, kp2, goodMatch[:10], None, flags=2)
cvshow('all_goodmatch_img', all_goodmatch_img)
cvshow('goodmatch_img', goodmatch_img)
原图:
图1与其SIFT关键点检测:
图2与其SIFT关键点检测:
match(画出所有goodmatch):
match(只画出前N个goodmatch)效果较好:
附实验原图(自取,网上随便找的埃菲尔铁塔的图):
最后说一下,本来也想实验一下PCV版本,把python2改成3可用的形式,又下载vlfeat各种配置实验,依旧有生成不了关键点文件的问题,改了很久依旧有报错,心态崩了就重新回来用cv2了,不过希望大家都能在网速好的时候安装opencv-contrib-python包,真的断了好多次,今天异常顺利!快乐!撒花结束一下~
---------------EchoZhang-------2020/04/02----------------------