python opencv之SIFT算法示例


Posted in Python onFebruary 24, 2018

本文介绍了python opencv之SIFT算法示例,分享给大家,具体如下:

目标:

学习SIFT算法的概念
学习在图像中查找SIFT关键的和描述符

原理:

(原理部分自己找了不少文章,内容中有不少自己理解和整理的东西,为了方便快速理解内容和能够快速理解原理,本文尽量不使用数学公式,仅仅使用文字来描述。本文中有很多引用别人文章的内容,仅供个人记录使用,若有错误,请指正出来,万分感谢)

之前的harris算法和Shi-Tomasi 算法,由于算法原理所致,具有旋转不变性,在目标图片发生旋转时依然能够获得相同的角点。但是如果对图像进行缩放以后,再使用之前的算法就会检测不出来,原理用一张图表示(图1):

python opencv之SIFT算法示例

(harris算法和shi-tomasi算法都是基于窗口中像素分布和变化的原理,在图像放大且窗口大小不发生变化的时,窗口中的像素信息则会有很大的不同,造成无法检测的结果)

SIFT特性:

  1. 独特性,也就是特征点可分辨性高,类似指纹,适合在海量数据中匹配。
  2. 多量性,提供的特征多。
  3. 高速性,就是速度快。
  4. 可扩展,能与其他特征向量联合使用。

SIFT特点:

  1. 旋转、缩放、平移不变性
  2. 解决图像仿射变换,投影变换的关键的匹配
  3. 光照影响小
  4. 目标遮挡影响小
  5. 噪声景物影响小

SIFT算法步骤:

  1. 尺度空间极值检测
  2. 关键点定位
  3. 关键点方向参数
  4. 关键点描述符
  5. 关键点匹配

尺度空间极值检测:

尺度空间的个人理解:
你找一张分辨率1024×1024图片,在电脑上观看,十分清晰,但是图片太大。现在把这图片反正photoshop上,将分辨率改成512×512,图片看着依然很清晰,但是不可能像1024×1024的画面那么精细,只不过是因为人眼构造的原因,512×512图片依然能让你分辨出这是个什么东西。

粗俗点说,尺度空间,就相当于一个图片需要获得多少分辨率的量级。如果把一个图片从原始分辨率到,不停的对其分辨率进行减少,然后将这些图片摞在一起,可以看成一个四棱锥的样式,这个东西就叫做图像金字塔(如下图,图2)。

python opencv之SIFT算法示例

再回到尺度空间,在摄像头中,计算机无法分辨一个景物的尺度信息。而人眼不同,除了人大脑里已经对物体有了基本的概念(例如正常人在十几米外看到苹果,和在近距离看到苹果,都能认出是苹果)以外,人眼在距离物体近时,能够获得物体足够多的特性,在距离物体远时,能够或略细节,例如,近距离看一个人脸能看到毛孔,距离远了看不到毛孔等等。

在图片信息当中,分辨率都是固定的,要想得到类似人眼的效果,就要把图片弄成不同的分辨率,制作成图像金字塔来模拟人眼的功能,从而在其他图片中进行特征识别时,能够像人眼睛一样,即使要识别的物体尺寸变大或者变小,也能够识别出来!

从图1可以看出,如果如果图像变大,窗口大小还是以前的大小,则无法正确检测出角点。那么很自然的就能想到,如果图片变大,咱们把窗口也放大不就行了? 这就需要上面提到的尺度空间发挥作用。

在SIFT当中,利用了一个叫做高斯核的方程来构建尺度空间,原因是高斯核函数是唯一多尺度空间的核。听起来比较晦涩,个人理解为:

高斯核函数在之前的高斯滤波当中使用过,其原理就是利用高斯分布的特性,在以某一个点为中心要进行以某一个窗口大小进行模糊的操作。那么,根据滤波的原理,距离中心像素点位置的距离越远的像素点,需要“模糊化效果”的值就应该越少。那么这个距离值的分配方法,就是利用满足高斯核函数的分配方法,由中心,到四周,符合高斯核函数的“钟型”曲线(从二维上看)。

那么尺度空间中的高斯核也可以这么理解,高斯核函数的参数有三个G(x,y,σ) ,在滤波当中,第三个参数σ在运算中是固定的一个值。而在尺度空间的构造当中,所谓的“尺度”,就是这个σ值变化,而x和y表示像素坐标。σ的值越小,图像被平滑(被模糊)的越少,尺度也越小。所以,大尺度图片可以对应成一个图像离远处观看,是个大致轮廓,小尺度图片可以对应成离近处观看,有更多细节。

构建尺度空间的目的是为了检测出在不同的尺度下都存在的特征点,如此可以获得缩放不变性

其中利用图像I(x,y)G(x,y,σ) 进行卷积运算,得到尺度空间L(x,y,σ),可以理解,所谓的“尺度空间”在这里就是这个函数L(x,y,σ)

如果求取特征点,可以使用一个叫做拉普拉斯算子进行运算

但是,由于拉普拉斯算子的效率太低,再SIFT算法当中使用差分来代替。

高斯金字塔:

在建立尺度空间后,需要找到关键点,此时需要实现高斯金字塔的构造来实现关键点的求取。在高斯金字塔当中,“塔”的每一层都是图像,“塔”的高度就是上面提到的尺度σ。“塔”的每一层对应一个σ值,同时将高斯金字塔中的图像分成组,每组当中图像的尺寸相同,但是尺度σ不同。具体尺度之间的计算关系,先忽略,如下图所示:

python opencv之SIFT算法示例

高斯差分金字塔DOG:

每一组相邻当中相邻两层的图像做差,得到的图像再“叠”成一个金字塔就是高斯差分金字塔DOG。

DOG局部特征点检测:

有了差分金字塔,现在便可以计算关键点(特征点)。由于金字塔的模型不是二维模型,而是一个三维模型,这里计算极值的方法也不再是二维求取极值的方法。

计算一个某一个点是否是局部最大值,在离散的三维空间当中,以该点为中心,检测它周围的点。类似魔方的中心位置一样,如下图中的“叉”就是待计算是否是局部极值点。

python opencv之SIFT算法示例

这里说明,局部极值点都是在同一个组当中进行的,所以肯定有这样的问题,某一组当中的第一个图和最后一个图层没有前一张图和下一张图,那该怎么计算? 解决办法是,在用高斯模糊,在高斯金字塔多“模糊”出三张来凑数,所以在DOG中多出两张。

关键点定位:

上面找到的关键点要进行处理,去除一些不好的特征点,保存下来的特征点能够满足稳定性等条件。

主要是去掉DOG局部曲率非常不对称的像素。

因为低对比度的特征点和边界点对光照和噪声变化非常敏感,所以要去掉。利用阈值的方法来限制,在opencv中为contrastThreshold。

去除低对比度的特征点:

使用泰勒公式对DOG函数空间进行拟合,去掉小于修正阈值的关键点。

去除不稳定的边界点:

利用Hessian矩阵(就是求导数的矩阵),利用边缘梯度的方向上主曲率值比较大,而沿着边缘方向则主曲率值较小的原理,将主曲率限制为某个值。满足该值条件的点留下,反之去除。

关键点设定方向参数:

每个关键点设置方向以后可以获得旋转不变性。

获取关键点所在尺度空间的邻域,然后计算该区域的梯度和方向,根据计算得到的结果创建方向直方图,直方图的峰值为主方向的参数,其他高于主方向百分之80的方向被判定为辅助方向,这样设定对稳定性有很大帮助。如图

python opencv之SIFT算法示例

关键点描述符:

经过上面的步骤计算,每个关键点有三个信息,位置、尺度、方向。所以具备平移、缩放、和旋转不变性。

接下来对每个关键点用一组向量将这个关键点描述出来,使其不随着光照、视角等等影响而改变。该描述符不但涉及关键点,而且还涉及到关键点周围的像素,使其有更强的不变特性。

基本原理是选取关键点周围16×16的像素区域,分成4个小块,每个小块创建8个bin的直方图,这总共的128个信息的向量就是关键点描述符的主要内容。此外还要测量,以达到光照、旋转的稳定性。如图

python opencv之SIFT算法示例

关键点匹配:

分别对模板图和实时图建立关键点描述符集合,通过对比关键点描述符来判断两个关键点是否相同。128个信息的向量使用欧氏距离来实现。

在关键点的匹配当中,使用的搜索算法为区域搜索算法当中最常用的k-d树实现。

比较之后,需要在进行消除错配点才算完成。

OpenCV 中的 SIFT:

关于opencv版本与SIFT算法不能调用的问题:

SIFT算法是一个有专利的算法,在商业用途上是收费的。对于穷B学生,算法的发明者还比较仁慈,可以使用。
不过,在python当中使用SIFT算法和版本之间有不少关系,源文档当中使用opencv版本是2.4.9版本,此版本可以随意使用SIFT算法。

但是,在opencv3当中就没那么幸运了,opencv中的很多特征点提取算法都和cv2中的库分离开,必须要添加opencv-contrib才可以使用,本人使用的opencv版本是3.3.0,几乎是最新的版本。

网上有一大堆教程关于如何在opencv当中如何添加opencv-contrib的教程,使用cmake,使用vs,啥的非常麻烦。

本人狗急跳墙,寻思在pip上面有没有啥第三方的库可以直接就将opencv-contrib这个库。

结果,还真找到了 哈哈。

这下方便了,只要在你的控制台当中输入
pip install opencv-contrib-python即可

如果pip安装不上去

直接上官方上面下个轮子,然后pip安装就能用了

网站在此!!!

import cv2
import numpy as np


img = cv2.imread('1.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()


kp = sift.detect(gray,None)#找到关键点

img=cv2.drawKeypoints(gray,kp,img)#绘制关键点

cv2.imshow('sp',img)
cv2.waitKey(0)

返回的关键点是一个带有很多不用属性的特殊结构体,属性当中有坐标,方向、角度等等。

计算关键点描述符:

使用sift.compute()函数来进行计算关键点描述符

kp,des = sift.compute(gray,kp)

如果未找到关键点,可使用函数sift.detectAndCompute()直接找到关键点并计算。

在第二个函数中,kp为关键点列表,des为numpy的数组,为关键点数目×128

sift = cv2.xfeatures2d.SIFT_create()

kp, des = sift.detectAndCompute(gray,None)

结果如图

python opencv之SIFT算法示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
学习python的几条建议分享
Feb 10 Python
Windows8下安装Python的BeautifulSoup
Jan 22 Python
Python使用time模块实现指定时间触发器示例
May 18 Python
Python入门之三角函数atan2()函数详解
Nov 08 Python
python3利用Socket实现通信的方法示例
May 06 Python
解决Python3 控制台输出InsecureRequestWarning问题
Jul 15 Python
详解python中的index函数用法
Aug 06 Python
Python Subprocess模块原理及实例
Aug 26 Python
Python中的四种交换数值的方法解析
Nov 18 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
Dec 27 Python
Django与AJAX实现网页动态数据显示的示例代码
Feb 24 Python
Python各协议下socket黏包问题原理
Apr 12 Python
python3 破解 geetest(极验)的滑块验证码功能
Feb 24 #Python
python opencv之SURF算法示例
Feb 24 #Python
几种实用的pythonic语法实例代码
Feb 24 #Python
使用Python爬取最好大学网大学排名
Feb 24 #Python
python opencv 直方图反向投影的方法
Feb 24 #Python
python爬虫爬取淘宝商品信息
Feb 23 #Python
python爬取淘宝商品详情页数据
Feb 23 #Python
You might like
世界收音机发展史
2021/03/01 无线电
一些被忽视的PHP函数(简单整理)
2010/04/30 PHP
PHP中usort在值相同时改变原始位置问题的解决方法
2011/11/27 PHP
php调用nginx的mod_zip模块打包ZIP文件
2014/06/11 PHP
微信 开发生成带参数的二维码的实例
2016/11/23 PHP
PHP的垃圾回收机制代码实例讲解
2021/02/27 PHP
js textarea自动增高并隐藏滚动条
2009/12/16 Javascript
js跟随滚动条滚动浮动代码
2009/12/31 Javascript
javascript在事件监听方面的兼容性小结
2010/04/07 Javascript
关于JavaScript定义类和对象的几种方式
2010/11/09 Javascript
jQuery去掉字符串起始和结尾的空格(多种方法实现)
2013/04/01 Javascript
浅析ajax请求json数据并用js解析(示例分析)
2013/07/13 Javascript
jquery判断小数点两位和自动删除小数两位后的数字
2014/03/19 Javascript
浅谈javascript原型链与继承
2015/07/13 Javascript
JavaScript 2048 游戏实例代码(简单易懂)
2016/03/25 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
利用C/C++编写node.js原生模块的方法教程
2017/07/07 Javascript
详解react-router4 异步加载路由两种方法
2017/09/12 Javascript
简化vuex的状态管理方案的方法
2018/06/02 Javascript
[02:43]2014DOTA2国际邀请赛 官方Alliance战队纪录片
2014/07/14 DOTA
[00:32]DOTA2上海特级锦标赛 Ehome战队宣传片
2016/03/03 DOTA
[01:23]2019完美世界全国高校联赛(春季赛)合肥全国总决赛
2019/06/10 DOTA
python中的五种异常处理机制介绍
2014/09/02 Python
python并发编程之多进程、多线程、异步和协程详解
2016/10/28 Python
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
Pycharm代码无法复制,无法选中删除,无法编辑的解决方法
2018/10/22 Python
CSS3新属性transition-property transform box-shadow实例学习
2013/06/06 HTML / CSS
完美解决IE8下不兼容rgba()的问题
2017/03/31 HTML / CSS
运动会解说词200字
2014/02/06 职场文书
校园环保标语
2014/06/13 职场文书
庆六一活动总结
2014/08/29 职场文书
考研复习计划
2015/01/19 职场文书
自我评价优缺点范文
2015/03/11 职场文书
运动会报道稿大全
2015/07/23 职场文书
小学语文的各类谚语(70首)
2019/08/15 职场文书
python绘制云雨图raincloud plot
2022/08/05 Python