尺度不变特征变换

尺度不变特征变换(Scale-Invariant Feature Transform,SIFT)是用于图像处理领域的一种描述,是一种局部特征描述子,具有尺度不变性,可在图像中检测出关键点。

SIFT算法是用于提取图像局部特征的经典算法,其实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。

SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换(Affine Transformation)和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。

OpenCV内置了SIFT算法的诸多函数,包括:

  • 实例化SIFT类的函数:cv2.xfeatures2d.SIFT_create()
  • 在图像中查找关键点的函数: sift.detect(gray, None)
  • 计算找到的关键点的描述符的函数: sift.compute(kp)
  • 在图中画出关键点的函数: cv2.drawKeypoints(gray, kp, img)

基于SIFT算法的图像特征检测:

import cv2 
import numpy as np 
'''
OpenCV2.4.13中没有drawMatchesKnn()函数,你需要从 https://github.com/opencv/opencv/blob/4.x/samples/python/ 中下载common.py和find_obj.py两个文件到当前程序所在的目录
'''
from find_obj import filter_matches,explore_match
from matplotlib import pyplot as plt

def getSift():
    '''
    定义函数用于获取并查看SIFT特征
    '''
    img_path1 = "C:\\Users\\libei\\Pictures\\e.jpg"
    #读取图像
    img = cv2.imread(img_path1)
    #将其转换为灰度图像
    gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #创建SIFT的类
    sift = cv2.xfeatures2d.SIFT_create()
    #在图像中找到关键点
    kp = sift.detect(gray,None)
    #Keypoint数据类型分析 
    print(kp[0].pt)
    #计算每个关键点的SIFT特征
    des = sift.compute(gray,kp)
    print(type(kp),type(des))
    #des[0]为关键点的list,des[1]为特征向量的矩阵
    print (type(des[0]), type(des[1]))
    print (des[0],des[1])
    print (des[1].shape)
    #在灰度图像中画出这些关键点
    img=cv2.drawKeypoints(gray,kp,np.array([]),(255,0,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    plt.imshow(img)
    plt.show()
    
if __name__ == '__main__':
  getSift()

输出结果如图所示

仅学术研究用

接着将两幅图像中的SIFT特征值进行匹配

import cv2 
from matplotlib import pyplot as plt 

img1 = cv2.imread("C:\\Users\\libei\\Pictures\\test.jpg",0) #载入第1幅测试图像
img2 = cv2.imread("C:\\Users\\libei\\Pictures\\e.jpg",0) #载入第2幅测试图像

# 初始化SIFT检测器
sift=cv2.xfeatures2d.SIFT_create()

# 通过SIFT检测器找到关键点kp和描述子des
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)

# 蛮力匹配算法,有两个参数,距离度量(L2(default),L1),是否交叉匹配(默认为false)
bf = cv2.BFMatcher()

#返回k个最佳匹配
matches = bf.knnMatch(des1,des2,k=2)
'''
OpenCV3.0的drawMatchesKnn()函数
比值测试,首先获取与A距离最近的点B(最近)和C(次近),只有当B/C小于阈值(示例中为0.75)时才被认为是匹配,
因为假设匹配是一一对应的,真正匹配的理想距离为0
'''
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good[:10], None,flags=2)
plt.axis('off')
plt.imshow(img3)
#plt.savefig('test1.jpg', dpi=300)
plt.show()

输出结果如图所示

仅学术研究用

其中的连线代表左边小图与右边小图之间SIFT特征可以匹配的图像点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值