一、SIFT(尺度不变特征变换)原理分析
在过去的十年间,最成功的图像局部描述子之一是尺度不变特征变换(SIFT),它是由David Lowe发明的。SIFT是用于图像处理领域的一种描述,SIFT特征包括兴趣点检测器和描述子,具有非常强的稳健性。
SIFT算法可以解决的问题:
•目标的旋转、缩放、平移(RST)
• 图像仿射/投影变换(视点viewpoint)
• 弱光照影响(illumination)
• 部分目标遮挡(occlusion)
• 杂物场景(clutter)
• 噪声
SIFT算法的特征:
•独特性,特征点可分辨性高。
•多量性,物体可提供的特征多。
•高速性,速度快。
•可扩展,与其他形式的特征向量进行联合较为方便。
SIFT算法的实现步骤:
SIFT算法的实质可以归为在不同尺度空间上查找特征点(关键点)的问题。
参照博客https://blog.csdn.net/rainbowbirds_aes/article/details/81298949,可以将SIFT算法分解为如下四步:
1.尺度空间极值检测,
2.关键点定位
3.关键点方向参数
4.关键点描述符
5.关键点匹配
SIFT算法实现特征匹配主要有三个流程,
1、提取关键点;
2、对关键点附加详细的信息(局部特征),即描述符;
3、通过特征点(附带上特征向量的关键点)的两两比较找出相互匹配的若干对特征点,建立景物间的对应关系。
二、Harris特征匹配处理
Harris角点检测算法是一个极为简单的角点检测算法。该算法的主要思想是,如果像素周围显示存在多于一个方向的边,我们认为该点为兴趣点。该点就称为角点。
以下是代码描述,把教材中的作为参考(http://yongyuan.name/pcvwithpython/chapter2.html):
其中,在实验运行中,出现了以下问题,
问题一:
提示print缺少括号,请一定记住,所有的print后面内容都要用括号括起来
问题二:
这时候只需要改成代码中的“/”改成"//"就可以解决,因为cv2.resize内的参数是要求为整数。
实验运行结果如下:从匹配结果可以看出,Harris特征匹配处理也有很大一部分匹配结果不正确。
二、SIFT特征匹配处理
使用SIFT算法我们要先下载Vlfeat。
首先登陆vlfeat官网 http://www.vlfeat.org/ 然后点击上方download会出现下图页面,
选择Downloads中的Previous versions …进入下载内容选择。
我下载的是vlfeat-0.9.20-bin.tar.gz,其中我们需要的仅是对应平台的可执行文件,我的系统是64位的,所以我选择的是64位的,将win64拷贝到你想放置的某个目录,我将其放置在计算机和pcv-master同一个目录下,并改名为win64vlfeat。
然后选择上面的PCV,进入PCV-master\PCV\localdescriptors这个目录下,可以看到有harris.py和sift.py两个文件,打开sift.py文件,找到以下这个地方
我们需要做的是:
1.在cmmd = str后面括号内加入之前我们安装的win64vlfeat文件夹中sift.exe的路径,记得在路径前加上r转义。
2.print后面要记得加括号。
简单测试下SIFT算法是否能够实现,以下是代码:
运行以后出现错误,在实现过程中无法找到sift文件。
这个错误请教同学以后解决了:
1.把win64vlfeat文件夹和pcv文件夹放在同一目录下,然后记得再进入PCV-master\PCV\localdescriptors这个目录下,找到sift.py文件并打开sift.py文件,找到以下这个地方并修改,
2.把pcv重装,在PCV\PCV-master的文件夹下找到setup.py文件,按下左shift键和鼠标右键,选择打开命令窗口,输入python setup.py install重装pcv包,测试一下,可以正常运行,以下是代码:
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 = 'empire.jpg'
im2f = '2.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, 'empire.exe')
l1, d1 = sift.read_features_from_file('empire.exe')
figure()
gray()
subplot(121)
sift.plot_features(im1, l1, circle=False)
sift.process_image(im2f, 'out_sift_2.txt')
l2, d2 = sift.read_features_from_file('out_sift_2.txt')
subplot(122)
sift.plot_features(im2, l2, circle=False)
#matches = sift.match(d1, d2)
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)
show()
实验运行结果:
从Harris和sift特征匹配处理的结果来看,可以明显地看出,sift算法的处理结果更好,匹配的关键点数目更多,匹配的结果也更加准确。