图像特征匹配算法-SIFT算法介绍及代码

一、SIFT算法

算法介绍

  1. SIFT (Scale Invariant Feature Transform) 算法,即尺度不变特征算法。

  2. 特点:该算法对图像存在的旋转、仿射变换,光照变化等能够保持不变性,对噪声的敏感度低,具有很强的鲁棒性。

  3. 缺点:
    ① 由于该算法主要是利用了所提取的特征点的局部邻域梯度信息,当待匹配图像中出现相似的部分时,此时会出现一 对多的现象。 (注:即A中一个特征点与B中多个相似的特征点进行了匹配)
    ② 此外,由于算法的原因,还存在较多的误匹配的点。
    (注:针对这个问题,众多学者提出了改进了SIFT算法,**文献[1]**中提出,在进行SIFT算法之后,利用马氏距离进行二次特征点匹配,**文献[2]**中提出引入RANSAC算法进行剔除错误匹配点)

SIFT算法特征点匹配步骤

①尺度空间极值检测——即找特征点
对于二维图像***I***(x,y),建立图像的DOG (difference of guassians,即高斯差分)金字塔,DOG尺度空间含义为:可以用一个尺度空间的高斯函数和图像的卷积来表示。

G为尺度可变的高斯函数,***I***为空间坐标,其中西伽马为尺度。

为确定特征点所在的位置,首先需要建立一个高斯金字塔。具体可以参考文献。
得到高斯金字塔后,再通过两个相邻的高斯尺度空间做差,得到高斯差分DOC金字塔,整个过程的公式如下:
在这https://mp.csdn.net/mdeditor#里插入图片描述
高斯差分金字塔建立后,特征点就是DOG尺度空间众多极值点,(个人认为对其进行求偏导数即可得到特征点的位置坐标),查找该极值点需要把每个点与邻域内的周围的26个点进行比较,这些点包括,在同一尺度上相邻的8个点,以及相邻尺度上相邻的18个点。

②特征点的尺度方向的确定
得到了特征点的坐标是完全不够的,必须要增加方向尺度信息。

  • 采用有限差分的方法,求出在以特征点为圆心,以3倍西伽马为半径的范围内的图像梯度的幅值和相位。
  • 利用直方图统计方法,求助邻域内所有像素点的梯度方向以及幅值。特征点的主方向就是直方图的峰值所代表的方向,确定了主方向就可以使SIFT算法具备旋转不变性
  • 主方向的计算公式为:(注:L表示特征点的尺度)
    在这里插入图片描述
    ③特征向量的生成
    特征向量最终是通过求得的特征点的邻域梯度信息来计算的。
  • 先把坐标轴位置旋转到特征点所在的主方向上
  • 接着以特征点为圆心,选择特征点附近的16个点作为种子点,分别求出8个方向上的梯度大小
  • 最后得到的128维向量即为所求的特征向量

④特征点的匹配
通常采用最邻近的方法,即查找每一个特征点在另外一副图像中的最邻近。即最短的欧式距离。
欧式距离的含义就是:两点连线的距离长度
具体如下:

  • 对目标图像A中的某个特征点,求出该点与图像B中的所有特征点的特征向量的欧式距离;
  • 将所求得的欧式距离值的大小进行排序;
  • 找出最小的和次小(倒数第二小的)欧式距离值对于的目标图B中的特征点,并对这两个距离的比值进行计算;
  • 假设该比值小于某个阈值,则这两个点为匹配点,否则不匹配。
    (注:该阈值是一个经验阈值:是影响误匹配的主要原因,实验中一般选取的阈值大小是0.6左右)

二、SIFT算法代码——python

特征点匹配代码

主要引用**文献[3]中,源代码见文献[4]**中, (注:源代码链接见参考文献)

import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('box.png',0)          # queryImage
img2 = cv2.imread('box_in_scene.png',0) # trainImage
# Initiate SIFT detector
sift = cv2.SIFT()
# find the keypoints and descriptors with SIFT
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)
# Apply ratio test
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])
# cv2.drawMatchesKnn expects list of lists as matches
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,flags=2)
plt.imshow(img3)

源代码如下图,见链接https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html#matcher
在这里插入图片描述
运行后结果如下图所示:在这里插入图片描述

SIFT算法还可以进行特征点的检测

代码引用博客上我第一个认识的大神的代码,见文献[5]: (注:源代码链接见参考文献)

import cv2

imgpath = '5.jpg'
img = cv2.imread(imgpath)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray, None)
img = cv2.drawKeypoints(image=img, outImage=img, keypoints=keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(51, 163, 236))
cv2.imshow('IMAGE', img)
while True:
    if cv2.waitKey() & 0xff == ord('q'):
        break
cv2.destroyAllWindows()

三、备注

本文本想针对SIFT算法的误匹配问题,结合文献[6],介绍SIFT算法匹配后,引入RANSAC算法进行误匹配点的剔除过程。但是此部分的代码还没搞明白,明白后结合原理及代码再写。

参考文献

[1]傅卫平,秦川,刘佳,杨世强,王雯. 基于SIFT算法的图像目标匹配与定位[J].仪器仪表学报,2011,32(01):163-169.
[2]完文韬,杨成禹. 改进的SIFT算法在图像特征点匹配中的应用[J].长春理工大学学报(自然科学 版),2018,41(01):44-47+52.
[3]1000sprites. 图像特征匹配总结[net].CSDN博客,2017,5,22:https://blog.csdn.net/ssw_1990/article/details/72629655.
[4]opencv. Feature Matching[net].https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html#goal.
[5]肥宅_Sean. SIFT角点检测(python)[net], CSDN博客,2018,7,25:https://blog.csdn.net/a19990412/article/details/81197354
[6]涂梅林,郭太良,林志贤.基于ORB特征的改进RANSAC匹配点提纯算法[J].有线电视技术,2018(08):18-22.

  • 2
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值