文章目录
一、实验基本原理
1、SIFT介绍
SIFT,即尺度不变特征变换,是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。SIFT特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、微视角改变的容忍度也相当高。
2、SIFT算法实现步骤
SIFT算法的实质可以归为在不同尺度空间上查找特征点(关键点)的问题。
SIFT算法实现特征匹配主要有三个流程:
1、提取关键点
2、对关键点附加详细的信息(局部特征),即描述符
3、通过特征点(附带上特征向量的关键点)的两两比较找出相互匹配的若干对特征点,建立景物间的对应关系
3、关键点检测的相关概念
-
关键点: 这些点是一些十分突出的点不会因光照、尺度、旋转等因素的改变而消 失,比如角点、边缘点、暗区域的亮点以及亮区域的暗点。既然两幅图像中 有相同的景物,那么使用某种方法分别提取各自的稳定点,这些点之间会有 相互对应的匹配点
-
尺度空间: 尺度空间理论最早于1962年提出,其主要思想是通过对原始图像进行尺度变换,获得图像多尺度下的空间表示。 从而实现边缘、角点检测和不同分辨率上的特征提取,以 满足特征点的尺度不变性。尺度空间中各尺度图像的 模糊程度逐渐变大,能够模拟 人在距离目标由近到远时目标 在视网膜上的形成过程。尺度越大图像越模糊。
-
尺度空间极值检测: 搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
-
关键点定位: 在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
-
方向确定: 基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
-
关键点描述: 在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。
4、RANSAC原理
RANSAC为Random Sample Consensus的缩写,它是根据一组包含异常数据的样本数据集,计算出数据的数学模型参数,得到有效样本数据的算法。
RANSAC算法的基本假设是样本中包含正确数据(inliers,可以被模型描述的数据),也包含异常数据(outliers,偏离正常范围很远、无法适应数学模型的数据),即数据集中含有噪声。这些异常数据可能是由于错误的测量、错误的假设、错误的计算等产生的。同时RANSAC也假设,给定一组正确的数据,存在可以计算出符合这些数据的模型参数的方法。
RANSAC基本思想描述如下:
- 考虑一个最小抽样集的势为n的模型(n为初始化模型参数所需的最小样本数)和一个样本集P,集合P的样本数#( P)>n,从P中随机抽取包含n个样本的P的子集S初始化模型M;
- 余集SC=P\S中与模型M的误差小于某一设定阈值t的样本集以及S构成 S ∗ S^* S∗。 S ∗ S^* S∗认为是内点集,它们构成S的一致集(Consensus Set);
- 若#( S ∗ S^* S∗)≥N,认为得到正确的模型参数,并利用集 S ∗ S^* S∗(内点inliers)采用最小二乘等方法重新计算新的模型 M ∗ M^* M∗;重新随机抽取新的S,重复以上过程。
- 在完成一定的抽样次数后,若未找到一致集则算法失败,否则选取抽样后得到的最大一致集判断内外点,算法结束。
5、实验中用到的工具包
VLFeat工具包 : 计算图像的 SIFT 特征
- process_image():将图像格式转化成.pgm格式,转换的结果以易读的形式保存在文本文件中
- read_features_from_file():从文件中读取特征属性值,然后将其以矩阵的形式返回
- plot_features():显示带有特征的图像
- match_twosided():返回特征点匹配情况
- plot_matches():显示特征匹配结果
二、SIFT特征提取与检索
1、对每张图片的SIFT的特征提取
代码:
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 = 'E:/code/image/second/15.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()
结果:
分析:
通过在不同的场景对每张图片的sift特征提取和角点检测,可以很容易的观察到,sift算法对关键点的识别更丰富,整体上sift算法效果大于harris算法 ,同时发现其中有张照片无法通过harris算法检测出特征点,尝试修改阈值依然无法识别,这在一定程度上说明了sift算法的稳定性也优于harris算法。
2、给定两张图片,计算其SIFT特征匹配结果
代码:
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 = '../data/sf_view1.jpg'
# im2f = '../data/sf_view2.jpg'
im1f = 'E:/code/image/second/f.jpg'
im2f = 'E:/code/image/second/g.jpg'
# im1f = '../data/climbing_1_small.jpg'
# im2f = '../data/climbing_2_small.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')
figure()
gray()
subplot(121)
sift.plot_features(im1, l1, circle=False)
sift.process_image(im2f,