python opencv之SURF算法示例


Posted in Python onFebruary 24, 2018

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

目标:

  1. SURF算法基础
  2. opencv总SURF算法的使用

原理:

上节课使用了SIFT算法,当时这种算法效率不高,需要更快速的算法。在06年有人提出了SURF算法“加速稳定特征”,从名字上来看,他是SIFT算法的加速版本。

(原文)
在SIFT算法当中使用高斯差分方程(Difference of Gaussian)对高斯拉普拉斯方程( Laplacian of Gaussian)进行近似。然而,SURF使用盒子滤波器进行近似,下面的图片显示了这种近似的方法。在进行卷积计算的时候可以利用积分图像,这是使用盒子形滤波器的一个优点,即计算某个窗口中的像素和的时候,计算量大小,也就是时间复杂度不受到窗口大小的影响。而且,这种运算可以在不用的尺度空间当中实现。

SURF算法计算关键点的尺度和位置信息使用Hessian矩阵实现。

(解释)
文中的高斯拉普拉斯方程(算子)是检测图像中斑点的一种十分常用的方法。以一维高斯函数来检测一维信号中的斑点为例。有一维信号f,高斯函数的一阶导数ddxg" role="presentation">,信号与高斯函数的一阶导数卷积后,会在边缘处出现极值。如图:

python opencv之SURF算法示例 

上面图片是在一维情况下,使用高斯函数的一阶导数的情况,另一种方法是使用高斯函数的二阶导数与信号进行卷积,高斯函数的二阶导数也叫做拉普拉斯变换。

但是,在一维信号斑点检测的实际情况当中,一个斑点可以考虑成是两个相邻的跳突组成,如下图。

python opencv之SURF算法示例 

类似于在图像当中,一个轮胎可以当成一个斑点,一个苍蝇也可以当成一个斑点。但是在使用高斯函数的二阶导数来检测斑点的时候,使用不同的高斯核(就是方差)运算不同大小的斑点时,计算出来的极值,即响应值会出现衰减。

此时,需要将高斯函数的二阶导数进行正规化,去除方差值不同导致响应值出现的衰减。

以上,是一维高斯函数检测一维信号的原理。二维的图像信号,使用二维高斯函数来检测斑点原理基本相同,此处的二维高斯函数的二阶导数,就叫做高斯拉普拉斯算子也就是LOG,通过改变不同的方差值,可以检测不同尺寸的二维斑点,如图。

python opencv之SURF算法示例

文中的高斯差分方程是SIFT算法当中,发明者想要利用两个相邻高斯尺度空间的图像相减来得到一个LOG的近似,因为这样做可以节省时间,而且可以控制精度变化,类似于高等数学当中泰勒公式那玩意-_- 。关于SIFT原理可以看上一篇博客

文中提到的积分图像实际上原理非常简单,类似递推方程。积分图像的目的是想建立一个函数,能够快速得到一个矩形图像区域当中所有像素值的和是多少。那么,设p(i,j)" role="presentation">表示从(0,0)" role="presentation">点到(i,j)" role="presentation">点的所有像素的和是多少,存储在p(i,j)" role="presentation">这个数组里面,如果想要获得W区域的像素和是多少,如图,只要计算p(i4,j4)p(i2,j2)p(i3,j3)+p(i1,j1)" role="presentation">即可。

python opencv之SURF算法示例 

如何求得p(i,j)" role="presentation">? 递推公式为,p(i,j)=p(i1,j)+p(i,j1)+I(i,j)p(i1,j1)" role="presentation">,这里面I(i,j)" role="presentation">表示像素点(i,j)" role="presentation">处的像素值。

文中提到的Hessian矩阵,学过数学分析、最优化、机器学习之类的人肯定对这玩意非常熟悉,实际上黑塞矩阵就是一个多元函数的二阶偏导数构成的方阵,它的行列式值(Determinant of Hessian )可以反映的局部结构信息,简称DOH。与LOG类似,DOH可以使用不同方差生成高斯函数对各个元的二阶偏导模板,以此来对图像进行卷积运算。 同样,DOH也会在卷积后的函数中,得到对图像信号斑点极值的响应。如图

python opencv之SURF算法示例

在SURF算法当中,黑塞矩阵中的L,即为二维高斯函数与图像的卷积,求得黑塞矩阵后,会得到如图。

python opencv之SURF算法示例

将上面得到的模板与图像的卷积转换为盒子滤波器,这里使用原文中的图像,如图。

python opencv之SURF算法示例

得到三个不同的盒子滤波器以后,对其进行近似和简化操作,并用其表示图像中某点的斑点响应值,遍历图像当中的所有像素,就得到了在某一尺度下斑点检测的响应图像。然后,利用不同的模板尺寸,获取多尺度斑点响应金字塔,在金字塔中搜索极值点,下面的操作就和SIFT算法类似了。

(原文)
为了给找到的特征点赋予方向,以特征点为中心,6s为半径获取水平和垂直小波响应运算结果,这里s是特征点尺度,同时使用高斯加权的方法。然后,他们会被绘制在如下图当中。其中,特征点的主方向估计运算是有一个弧度为60的扇形窗口,在滑动的过程中不断计算其中的响应值之和。有趣的是,小波响应值在任意尺度下使用积分图像很容易被获取。但是在多数情况下,旋转不变性不是必须的,可以代码当中将这一步取消,这样还能够提高算法计算速度,而且在+-15度的情况也保持稳定,此时该方法称作 U-SURF。用户可以设置upright参数,当参数为0计算方向,参数为1不计算方向。

python opencv之SURF算法示例

对于特征点描述的建立,SURF再一次使用Haar小波响应,同时使用积分图像使操作变得简单。在一个矩形区域当中,以特征点为中心,划取周围20s×20s区域的大小,以特征点为原点,主方向为横轴,分成四个子区域,每个子区域使用2s的Haar小波响应,对于每个子区域,获取一个向量,记录垂直、水平方向上的小波响应值,如图。

python opencv之SURF算法示例 

这个特征描述符的长度使64,降低维度可以加速计算,又可以区分特征。为了更好的区分特征点,SURF还使用了长度为128特征描述符。当dy小于0或者大于0时,计算dx或|dx|的和。同样,根据dx的符号计算不同的dy和。因此能够获得双倍的特征。计算复杂度也不会增加。opencv当中的extended参数为0或1时分别对应64和128的特征。

另外一个重要的改善是对潜在的兴趣点使用了拉普拉斯算子符号(黑塞矩阵的迹)。由于之前的计算已经完成对黑塞矩阵的构造,所以这步不会增加复杂度。

拉普拉斯符号在不同明暗背景下区分不同亮度的斑点,在匹配阶段,我们只需要比较拥有相同对比度的特征是否匹配即可,这样加快了计算速度,如图。

python opencv之SURF算法示例 

SURF算法的速度是SIFT速度的3倍,善于处理模糊和旋转的图像,但是不善于处理视角变化和关照变化。

(解释)
文中的小波响应运算,全称是haar小波运算。这里使用haar小波目的是为了获取图像梯度,使用之前计算好的图像积分结果,这样能够提高计算速度。与SIFT算法类似,在对每个特征点获取主方向时,使用原文中提到的一个π/3大小的扇形窗口,同时以0.2弧度为步长旋转滑动此窗口,在每个窗口当中对的haar响应值的水平方向,垂直方向进行累加。由于时使用一个圆形区域,转换成类似极坐标矢量的方式来表示,每个窗口中的结果(mw,θw)" role="presentation">,如图。

python opencv之SURF算法示例

主方向最大Haar响应值累加对应的方向。其中,如果除了主方向,还有其它方向的响应累加值较大,算法当中还会额外添加一个特征点,并赋予另外一个次大方向。

文中建立的特征描述符顾名思义,就是描述一个特征点的一组向量,里面唯一确定了一个特征。SURF获取主方向后,需要获取特征点描述子。以特征点为原点,主方向为横轴建立一个二维坐标系,区域大小是20s×20s,分成是个之块,每个子块利用2s的haar模板进行响应计算。然后统计ΣdxΣ|dx|ΣdyΣ|dy|" role="presentation">,每个20s的窗口分成4×4的子窗口,每个子窗口中又5s×5s个像元。如图

python opencv之SURF算法示例 

又4×4个子块,每个子块里面记录四个值,所以描述子一共又4×4×4=64个特征。

最后将沿着主方向的小波响应值扭转过来,原理就是简单的旋转矩阵。

代码部分

opencv里面提供的SURF算法和SIFT差不多,这两个玩意都是受到版权保护的,如果你是用pip 一条命令安装的opencv,那么恭喜你用不了SURF和SIFT算法,印象中只有2.4.9版本的opencv库才可以使用。

不过,办法还是有的,再控制台当中输入pip install opencv-contrib-python 就可以用了。

如果还是无法安装,可以直接网站早opencv-contrib-python的轮子,然后放到对应的文件下安装就行了。

我的版本是opencv 3.2,和教程文档中的使用方法不同。

详细参数可以自己去查一查,一查一个准的

https://docs.opencv.org/master/d5/df7/classcv_1_1xfeatures2d_1_1SURF.html

import cv2 
import numpy as np 

img = cv2.imread('feng.jpg')

#参数为hessian矩阵的阈值
surf = cv2.xfeatures2d.SURF_create(400)
#找到关键点和描述符
key_query,desc_query = surf.detectAndCompute(img,None)
#把特征点标记到图片上
img=cv2.drawKeypoints(img,key_query,img)

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

python opencv之SURF算法示例

凤的嘴上特征点占了这么多,辨识度还是蛮高的~ -_-|||

下面是设置方向,和输出一些值的方法

import cv2 
import numpy as np 

img = cv2.imread('feng.jpg')

#参数为hessian矩阵的阈值
surf = cv2.xfeatures2d.SURF_create(4000)

#设置是否要检测方向
surf.setUpright(True)

#输出设置值
print(surf.getUpright())

#找到关键点和描述符
key_query,desc_query = surf.detectAndCompute(img,None)

img=cv2.drawKeypoints(img,key_query,img)

#输出描述符的个数
print(surf.descriptorSize())


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

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

Python 相关文章推荐
Python实现变量数值交换及判断数组是否含有某个元素的方法
Sep 18 Python
Python批量更改文件名的实现方法
Oct 29 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
Feb 03 Python
python实现将excel文件转化成CSV格式
Mar 22 Python
网红编程语言Python将纳入高考你怎么看?
Jun 07 Python
python3第三方爬虫库BeautifulSoup4安装教程
Jun 19 Python
教你如何编写、保存与运行Python程序的方法
Jul 12 Python
关于tensorflow的几种参数初始化方法小结
Jan 04 Python
如何基于Python实现数字类型转换
Feb 07 Python
python实现PCA降维的示例详解
Feb 24 Python
基于OpenCV的网络实时视频流传输的实现
Nov 15 Python
Python爬取某平台短视频的方法
Feb 08 Python
几种实用的pythonic语法实例代码
Feb 24 #Python
使用Python爬取最好大学网大学排名
Feb 24 #Python
python opencv 直方图反向投影的方法
Feb 24 #Python
python爬虫爬取淘宝商品信息
Feb 23 #Python
python爬取淘宝商品详情页数据
Feb 23 #Python
Python如何抓取天猫商品详细信息及交易记录
Feb 23 #Python
python列表生成式与列表生成器的使用
Feb 23 #Python
You might like
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
PHP大文件分片上传的实现方法
2018/10/28 PHP
Javascript this 的一些学习总结
2012/08/02 Javascript
jquery属性过滤选择器使用示例
2013/06/18 Javascript
Nodejs关于gzip/deflate压缩详解
2015/03/04 NodeJs
javascript递归回溯法解八皇后问题
2015/04/22 Javascript
js省市联动效果完整实例代码
2015/12/09 Javascript
Jquery实现简单的轮播效果(代码管用)
2016/03/14 Javascript
使用ajaxfileupload.js实现上传文件功能
2016/08/13 Javascript
JS实现的Unicode编码转换操作示例
2017/04/28 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
jQuery实现的简单无刷新评论功能示例
2017/11/08 jQuery
element-ui 表格实现单元格可编辑的示例
2018/02/26 Javascript
vue多级复杂列表展开/折叠及全选/分组全选实现
2018/11/05 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
2019/03/07 Javascript
[01:02:04]EG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
python基础教程之分支、循环简单用法
2016/06/16 Python
python字典DICT类型合并详解
2017/08/17 Python
Django+JS 实现点击头像即可更改头像的方法示例
2018/12/26 Python
Python提取特定时间段内数据的方法实例
2019/04/01 Python
Django import export实现数据库导入导出方式
2020/04/03 Python
Anaconda的安装及其环境变量的配置详解
2020/04/22 Python
玩具反斗城西班牙网上商城:ToysRUs西班牙
2017/01/19 全球购物
怀旧收藏品和经典纪念品:Betty’s Attic
2018/08/29 全球购物
Strathberry苏贝瑞中国官网:西班牙高级工匠手工打造
2020/10/19 全球购物
《美丽的小路》教学反思
2014/02/26 职场文书
业务员的岗位职责
2014/03/15 职场文书
公务员培的训心得体会
2014/09/01 职场文书
秋季运动会演讲稿
2014/09/16 职场文书
平安建设汇报材料
2014/12/29 职场文书
2015年村计划生育工作总结
2015/04/28 职场文书
2015年法务工作总结范文
2015/05/23 职场文书
功夫熊猫观后感
2015/06/10 职场文书
党员读书活动心得体会
2016/01/14 职场文书
工作建议书范文
2019/07/08 职场文书
Python实现单例模式的5种方法
2021/06/15 Python