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 相关文章推荐
仅用50行代码实现一个Python编写的计算器的教程
Apr 17 Python
Python的Flask框架中实现分页功能的教程
Apr 20 Python
Python django实现简单的邮件系统发送邮件功能
Jul 14 Python
python 统计一个列表当中的每一个元素出现了多少次的方法
Nov 14 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
Dec 18 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
Dec 19 Python
python中使用 xlwt 操作excel的常见方法与问题
Jan 13 Python
对python dataframe逻辑取值的方法详解
Jan 30 Python
python实现微信小程序用户登录、模板推送
Aug 28 Python
Python pip安装模块提示错误解决方案
May 22 Python
PyCharm中关于安装第三方包的三个建议
Sep 17 Python
Opencv中cv2.floodFill算法的使用
Jun 18 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
一家之言的经验之谈php+mysql扎实个人基本功
2008/03/27 PHP
PHP删除数组中空值的方法介绍
2014/04/14 PHP
PHP函数getenv简介和使用实例
2014/05/12 PHP
利用php生成验证码
2017/02/23 PHP
Laravel使用消息队列需要注意的一些问题
2017/12/13 PHP
理解Javascript_03_javascript全局观
2010/10/11 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
javascript记住用户名和登录密码(两种方式)
2015/08/04 Javascript
JS图片等比例缩放方法完整示例
2016/08/03 Javascript
轻松掌握JavaScript中介者模式
2016/08/26 Javascript
jQuery代码实现实时获取时间
2017/01/29 Javascript
Angular 4.x 动态创建表单实例
2017/04/25 Javascript
JavaScript之json_动力节点Java学院整理
2017/06/29 Javascript
详谈表单重复提交的三种情况及解决方法
2017/08/16 Javascript
javascript实现QQ空间相册展示源码
2017/12/12 Javascript
Webpack打包字体font-awesome的方法示例
2018/04/26 Javascript
对Layer弹窗使用及返回数据接收的实例详解
2019/09/26 Javascript
React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析
2020/01/06 Javascript
jQuery插件simplePagination的使用方法示例
2020/04/28 jQuery
python中cPickle用法例子分享
2014/01/03 Python
python实现百度关键词排名查询
2014/03/30 Python
Python不规范的日期字符串处理类
2014/06/10 Python
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
深入理解python中的select模块
2017/04/23 Python
python+django+sql学生信息管理后台开发
2018/01/11 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
python打开使用的方法
2019/09/30 Python
PyCharm使用之配置SSH Interpreter的方法步骤
2019/12/26 Python
Pytorch之卷积层的使用详解
2019/12/31 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
2020/02/29 Python
Pycharm修改python路径过程图解
2020/05/22 Python
香港最新科技与优质家居产品购物网站:J SELECT
2018/08/21 全球购物
护士辞职信范文
2014/01/19 职场文书
网站美工岗位职责
2014/04/02 职场文书
金融保险专业求职信
2014/09/03 职场文书
2015年学校财务工作总结
2015/05/19 职场文书