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中声明只包含一个元素的元组数据方法
Aug 25 Python
Python用Bottle轻量级框架进行Web开发
Jun 08 Python
用pickle存储Python的原生对象方法
Apr 28 Python
Python安装模块的常见问题及解决方法
Feb 05 Python
Python3.6日志Logging模块简单用法示例
Jun 14 Python
Python 最大概率法进行汉语切分的方法
Dec 14 Python
python使用BeautifulSoup与正则表达式爬取时光网不同地区top100电影并对比
Apr 15 Python
简单了解python单例模式的几种写法
Jul 01 Python
python实现简单日志记录库glog的使用
Dec 13 Python
python闭包、深浅拷贝、垃圾回收、with语句知识点汇总
Mar 11 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
Apr 08 Python
python实现数学模型(插值、拟合和微分方程)
Nov 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
PHP 文件上传全攻略
2010/04/28 PHP
php防止恶意刷新与刷票的方法
2014/11/21 PHP
mac下多个php版本快速切换的方法
2016/10/09 PHP
更正确的asp冒泡排序
2007/05/24 Javascript
Javascript 继承实现例子
2009/08/12 Javascript
一个简单的JS时间控件示例代码(JS时分秒时间控件)
2013/11/22 Javascript
js加载读取内容及显示与隐藏div示例
2014/02/13 Javascript
实现placeholder效果的方案汇总
2015/06/11 Javascript
JQ实现新浪游戏首页幻灯片
2015/07/29 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记8)
2015/12/24 Javascript
react.js 获取真实的DOM节点实例(必看)
2017/04/17 Javascript
Angular 5.0 来了! 有这些大变化
2017/11/15 Javascript
Vue中的vue-resource示例详解
2018/11/02 Javascript
js实现单元格拖拽效果
2020/02/10 Javascript
Angular+ionic实现折叠展开效果的示例代码
2020/07/29 Javascript
v-slot和slot、slot-scope之间相互替换实例
2020/09/04 Javascript
wxpython中自定义事件的实现与使用方法分析
2016/07/21 Python
Python基于identicon库创建类似Github上用的头像功能
2017/09/25 Python
Python实现PS滤镜的万花筒效果示例
2018/01/23 Python
python使用itchat实现手机控制电脑
2018/02/22 Python
python pandas模块基础学习详解
2019/07/03 Python
基于python二叉树的构造和打印例子
2019/08/09 Python
Python使用get_text()方法从大段html中提取文本的实例
2019/08/27 Python
解决python中的幂函数、指数函数问题
2019/11/25 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
2019/12/18 Python
python 6.7 编写printTable()函数表格打印(完整代码)
2020/03/25 Python
python打开文件的方式有哪些
2020/06/29 Python
python中time、datetime模块的使用
2020/12/14 Python
HTML5 图片悬停放大的实现代码示例
2019/12/04 HTML / CSS
施工单位安全责任书
2014/07/24 职场文书
群众路线教育实践活动批评与自我批评
2014/09/15 职场文书
《微笑着面对生活》优秀演讲稿范文
2014/09/23 职场文书
学校捐款活动总结
2015/05/09 职场文书
读《方与圆》有感:交友方圆有度
2020/01/14 职场文书
PHP设计模式(观察者模式)
2021/07/07 PHP
Python 恐龙跑跑小游戏实现流程
2022/02/15 Python