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中使用HTML模版的教程
Apr 29 Python
Python判断字符串与大小写转换
Jun 08 Python
Python连接DB2数据库
Aug 27 Python
Python爬虫:通过关键字爬取百度图片
Feb 17 Python
Python3使用turtle绘制超立方体图形示例
Jun 19 Python
python实现猜单词小游戏
May 22 Python
Pyqt5 基本界面组件之inputDialog的使用
Jun 25 Python
opencv python图像梯度实例详解
Feb 04 Python
Python如何实现在字符串里嵌入双引号或者单引号
Mar 02 Python
python 负数取模运算实例
Jun 03 Python
matplotlib对象拾取事件处理的实现
Jan 14 Python
用Python写一个简易版弹球游戏
Apr 13 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
PHP5下$_SERVER变量不再受magic_quotes_gpc保护的弥补方法
2012/10/31 PHP
利用php+mcDropdown实现文件路径可在下拉框选择
2013/08/07 PHP
php清除和销毁session的方法分析
2015/03/19 PHP
Zend Framework教程之资源(Resources)用法实例详解
2016/03/14 PHP
Smarty简单生成表单元素的方法示例
2016/05/23 PHP
php生成图片缩略图功能示例
2017/02/22 PHP
postman的安装与使用方法(模拟Get和Post请求)
2018/08/06 PHP
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
php + ajax 实现的写入数据库操作简单示例
2020/05/16 PHP
Ext面向对象开发实践(续)
2008/11/18 Javascript
javascript实现动态侧边栏代码
2014/02/19 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
2015/10/21 Javascript
jQuery操作属性和样式详解
2016/04/13 Javascript
微信小程序  wx.request合法域名配置详解
2016/11/23 Javascript
vuejs响应用户事件(如点击事件)
2017/03/14 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
2018/01/12 Javascript
浅谈vue项目重构技术要点和总结
2018/01/23 Javascript
在Node.js下运用MQTT协议实现即时通讯及离线推送的方法
2019/01/24 Javascript
Vue项目部署的实现(阿里云+Nginx代理+PM2)
2019/03/26 Javascript
详解JavaScript实现动态的轮播图效果
2019/04/29 Javascript
Vue将页面导出为图片或者PDF
2020/08/17 Javascript
layui点击按钮页面会自动刷新的解决方案
2019/10/25 Javascript
Python3指定路径寻找符合匹配模式文件
2015/05/22 Python
Django操作session 的方法
2020/03/09 Python
Python pexpect模块及shell脚本except原理解析
2020/08/03 Python
HTML5探秘:用requestAnimationFrame优化Web动画
2018/06/03 HTML / CSS
加拿大时装零售商:Influence U
2018/12/22 全球购物
巴西箱包、背包、钱包和旅行配件购物网站:Inovathi
2019/12/14 全球购物
应届医学毕业生求职信分享
2013/12/02 职场文书
实习生自我评价
2014/01/18 职场文书
大学生优秀自荐信范文
2014/02/25 职场文书
2014年关于两会精神的心得体会
2014/03/17 职场文书
教师职业道德事迹材料
2014/08/18 职场文书
就业协议书盖章的注意事项
2014/09/28 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
结婚保证书(三从四德)
2015/02/26 职场文书