SIFT特征提取+匹配

别说谁变了你拦得住时间么 提交于 2020-03-08 10:51:11

SIFT特征提取+匹配

目录

SIFT特征提取+匹配

1. 算法描述

1.1 构建尺度空间

1.2  LoG近似DoG找到关键点

1.3 除去不好的特征点

1.4 关键点的表示

1.5 关键点描述子的生成​

1.6 根据SIFT进行匹配

2. 实验要求

3.实验过程

3.1 实验数据集

3.2 sift特征提取

3.3 特征匹配

3.4 匹配筛选

4. 总结

4.1 SIFT特征特性:

4.2 SIFT特征的缺点

4.3 SIFT特征的用途

4.4 实验过程遇到的问题


1. 算法描述

特征描述子就是对关键点提取特征的过程,应该具备可重复性、可区分性、准确性、有效性和鲁棒性。SIFT(Scale-Invariant Feature Transform)是一种特征描述子。该描述子具有尺度不变性和光照不变性。

1.1 构建尺度空间

这里的尺度可以理解为图像的模糊程度,就是眼睛近视的度数。尺度越大细节越少,SIFT特征希望提取所有尺度上的信息,所以对图像构建尺度空间, 也就是实用不同的平滑核对图像进行平滑。这里的平滑核选用高斯核,空间尺度有高斯核尺度决定:

其中

是原图像,*是卷积符号,

对应尺度下的尺度图像,

是高斯核。

其中 G(x,y,σ) 是尺度可变高斯函数

(x,y)是空间坐标,是尺度坐标。σ大小决定图像的平滑程度,大尺度对应图像的概貌特征,小尺度对应图像的细节特征。大的σ值对应粗糙尺度(低分辨率),反之,对应精细尺度(高分辨率)。

图像金字塔的建立:对于一幅图像I,建立其在不同尺度(scale)的图像,也成为子八度(octave),这是为了scale-invariant,也就是在任何尺度都能够有对应的特征点,第一个子八度的scale为原图大小,后面每个octave为上一个octave降采样的结果,即原图的1/4(长宽分别减半),构成下一个子八度(高一层金字塔)。

尺度空间的所有取值,i为octave的塔数(第几个塔),s为每塔层数

由图片size决定建几个塔,每塔几层图像(S一般为3-5层)。0塔的第0层是原始图像(或你double后的图像),往上每一层是对其下一层进行Laplacian变换(高斯卷积,其中σ值渐大,例如可以是σ, k*σ, k*k*σ…),直观上看来越往上图片越模糊。塔间的图片是降采样关系,例如1塔的第0层可以由0塔的第3层down sample得到,然后进行与0塔类似的高斯卷积操作。

1.2  LoG近似DoG找到关键点

为了寻找尺度空间的极值点,每一个采样点要和它所有的相邻点比较,看其是否比它的图像域和尺度域的相邻点大或者小。如图所示,中间的检测点和它同尺度的8个相邻点和上下相邻尺度对应的9×2个点共26个点比较,以确保在尺度空间和二维图像空间都检测到极值点。 一个点如果在DOG尺度空间本层以及上下两层的26个领域中是最大或最小值时,就认为该点是图像在该尺度下的一个特征点,如图所示。

同一组中的相邻尺度(由于k的取值关系,肯定是上下层)之间进行寻找

s=3的情况

在极值比较的过程中,每一组图像的首末两层是无法进行极值比较的,为了满足尺度变化的连续性,我们在每一组图像的顶层继续用高斯模糊生成了 3 幅图像,高斯金字塔有每组S+3层图像。DOG金字塔每组有S+2层图像.

1.3 除去不好的特征点

这一步本质上要去掉DoG局部曲率非常不对称的像素。

通过拟和三维二次函数以精确确定关键点的位置和尺度(达到亚像素精度),同时去除低对比度的关键点和不稳定的边缘响应点(因为DoG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力,在这里使用近似Harris Corner检测器。

①空间尺度函数泰勒展开式如下:,对上式求导,并令其为0,得到精确的位置, 得

②在已经检测到的特征点中,要去掉低对比度的特征点和不稳定的边缘响应点。去除低对比度的点:把公式(2)代入公式(1),即在DoG Space的极值点处D(x)取值,只取前两项可得:

若   ,该特征点就保留下来,否则丢弃。

③边缘响应的去除
一个定义不好的高斯差分算子的极值在横跨边缘的地方有较大的主曲率,而在垂直边缘的方向有较小的主曲率。主曲率通过一个2×2 的Hessian矩阵H求出:

导数由采样点相邻差估计得到。

 

D的主曲率和H的特征值成正比,令α为较大特征值,β为较小的特征值,则


令α=γβ,则

 (r + 1)2/r的值在两个特征值相等的时候最小,随着r的增大而增大,因此,为了检测主曲率是否在某域值r下,只需检测

1339034424_8705.jpg

转存失败重新上传取消
if (α+β)/ αβ> (r+1)2/r, throw it out.   在Lowe的文章中,取r=10。

1.4 关键点的表示

上一步中确定了每幅图中的特征点,为每个特征点计算一个方向,依照这个方向做进一步的计算, 利用关键点邻域像素的梯度方向分布特性为每个关键点指定方向参数,使算子具备旋转不变性。


为(x,y)处梯度的模值和方向公式。其中L所用的尺度为每个关键点各自所在的尺度。至此,图像的关键点已经检测完毕,每个关键点有三个信息:位置,所处尺度、方向,由此可以确定一个SIFT特征区域。

1.5 关键点描述子的生成

首先将坐标轴旋转为关键点的方向,以确保旋转不变性。以关键点为中心取8×8的窗口。

Figure.16*16的图中其中1/4的特征点梯度方向及scale,右图为其加权到8个主方向后的效果。

图左部分的中央为当前关键点的位置,每个小格代表关键点邻域所在尺度空间的一个像素,利用公式求得每个像素的梯度幅值与梯度方向,箭头方向代表该像素的梯度方向,箭头长度代表梯度模值,然后用高斯窗口对其进行加权运算。

图中蓝色的圈代表高斯加权的范围(越靠近关键点的像素梯度方向信息贡献越大)。然后在每4×4的小块上计算8个方向的梯度方向直方图,绘制每个梯度方向的累加值,即可形成一个种子点,如图右部分示。此图中一个关键点由2×2共4个种子点组成,每个种子点有8个方向向量信息。这种邻域方向性信息联合的思想增强了算法抗噪声的能力,同时对于含有定位误差的特征匹配也提供了较好的容错性。
计算keypoint周围的16*16的window中每一个像素的梯度,而且使用高斯下降函数降低远离中心的权重。

在每个4*4的1/16象限中,通过加权梯度值加到直方图8个方向区间中的一个,计算出一个梯度方向直方图。

这样就可以对每个feature形成一个4*4*8=128维的描述子,每一维都可以表示4*4个格子中一个的scale/orientation. 将这个向量归一化之后,就进一步去除了光照的影响。

1.6 根据SIFT进行匹配

生成了A、B两幅图的描述子,(分别是k1*128维和k2*128维),就将两图中各个scale(所有scale)的描述子进行匹配,匹配上128维即可表示两个特征点匹配上了。当两幅图像的SIFT特征向量生成后,下一步我们采用关键点特征向量的欧式距离来作为两幅图像中关键点的相似性判定度量。取图像1中的某个关键点,并找出其与图像2中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离少于某个比例阈值,则接受这一对匹配点。降低这个比例阈值,SIFT匹配点数目会减少,但更加稳定。最近邻距离与次近邻距离的方法,距离比率ratio小于某个阈值的认为是正确匹配。

建议的ratio取值原则如下:

ratio=0. 4 对于准确度要求高的匹配;
ratio=0. 6 对于匹配点数目要求比较多的匹配; 
ratio=0. 5 一般情况下。
也可按如下原则:当最近邻距离<200时ratio=0. 6,反之ratio=0. 4。ratio的取值策略能排分错误匹配点。

2. 实验要求

(1) 针对自己所处的环境,拍摄多张图片(注意要来自不同场景),构造出一个小的数据集(15张以上)

(2) 实现数据集中,每张图片的SIFT特征提取,并展示特征点

(3) 给定两张图片,计算其SIFT特征匹配结果

(4)给定一张输入的图片,在数据集内部进行检索,输出与其匹配最多的三张图片

比如输入:

3.实验过程

3.1 实验数据集

3.2 sift特征提取

3.2.1 源代码

# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from PCV.localdescriptors import sift
from PCV.localdescriptors import harris

# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:/windows/fonts/SimSun.ttc", size=14)

imname = 'D:/ComputerVision_code/img/sdl11.jpg'
im = array(Image.open(imname).convert('L'))
sift.process_image(imname, 'empire.sift')
l1, d1 = sift.read_features_from_file('empire.sift')

figure()
gray()
subplot(121)
sift.plot_features(im, l1, circle=False)
title(u'SIFT特征',fontproperties=font)

# 检测harris角点
harrisim = harris.compute_harris_response(im)

subplot(122)
filtered_coords = harris.get_harris_points(harrisim, 6, 0.1)
imshow(im)
plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
axis('off')
title(u'Harris角点',fontproperties=font)

show()

3.2.2 图片特征提取结果

3.2.3 小结

sift描述子同Harris角点算法一样,具有尺度不变性、光照不变性和旋转不变性的特点,但两个算法检测的结果能看到明显的区别,sift算法检测到的特征点明显比Harris算法的更多,更丰富,而且运算速度比较快,定位精度也比较高,体现出了sift算法特征检测的优越性。

 

3.3 特征匹配

3.3.1 源代码

from PIL import Image
from pylab import *
import sys
from PCV.localdescriptors import sift

if len(sys.argv) >= 3:
  im1f, im2f = sys.argv[1], sys.argv[2]
else:

  im1f = 'D:/ComputerVision_code/img/sdl11.jpg'
  im2f = 'D:/ComputerVision_code/img/sdl12.jpg'

im1 = array(Image.open(im1f))
im2 = array(Image.open(im2f))

sift.process_image(im1f, 'out_sift_1.txt')
l1, d1 = sift.read_features_from_file('out_sift_1.txt')

sift.process_image(im2f, 'out_sift_2.txt')
l2, d2 = sift.read_features_from_file('out_sift_2.txt')

matches = sift.match_twosided(d1, d2)
print ('{} matches'.format(len(matches.nonzero()[0]))) 

figure()
gray()
sift.plot_matches(im1, im2, l1, l2, matches, show_below=True)
title('{} matches'.format(len(matches.nonzero()[0])))#设置子图标题

show()

3.3.2 匹配结果

 

3.3.3 小结

从以上两个试验及结果可以看出sift算法匹配的精准度还是挺高的,虽然没能做到每一个特征点都对应起来(这当然也有图片角度不同,特征点不同不能找到匹配点的因素在),但是从埃菲尔铁塔的这组实验可看出,已经匹配的特征点,精准度非常高。

3.4 匹配筛选

3.4.1 输入一张数据集以外的照片:

3.4.2 匹配结果

3.4.3 小结

背景模糊不清晰,还有图片像素的大小会影响到sift特征点检测算法的效果;同一角度拍摄的图片匹配度会更高,但是旋转,明暗程度,图中物体尺寸的大小都不会影响到sift算法的检测效果,因此他具有较高的稳定性和准确性,以及从大量图片中检测到目标图片的高效性。

4. 总结

4.1 SIFT特征特性:

  • 尺度不变性

  • 旋转不变性

  • 光照不变性

  • 鉴别性强,信息量丰富

4.2 SIFT特征的缺点

  • 实时性不高,因为不断的下采样和插值等操作

  • 对于边缘光滑的目标无法准确提取特征点

4.3 SIFT特征的用途

主要解决图像配准和目标识别跟踪中下述问题

  • 目标的旋转、缩放、平移

  • 图像的仿射/射影变换

  • 部分减轻光照影响

  • 目标的部分遮挡

  • 杂物场景

  • 噪声

4.4 实验过程遇到的问题

1.环境配置问题,之前下载的是vlfeat-0.9.21版本的,代码运行后有错,后来下载了vlfeat-0.9.20版本,将其解压,复制其中的bin文件夹放在项目文件夹下,修改PCV中localdescriptors文件夹中的sift.py(用记事本,或编辑器打开),修改其中 :cmmd = str(r"项目文件夹下的sift.exe路径"+imagname+"--output="+resultname+" "+params),在运行代码就成功了!

2.有些图片Harris角点检测算法检测不出来角点;

3.在进行sift特征点匹配时,大部分图片匹配后的匹配率很低,甚至为零,不知道是照片像素的原因还是相匹配的图片尺寸不同的原因。

 

 

 

 

参考:

1.https://blog.csdn.net/abcjennifer/article/details/7639681

2.https://www.cnblogs.com/YiXiaoZhou/p/5893835.html

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!