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

目标:

SURF算法基础

opencv总SURF算法的使用

原理:

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

(原文)

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

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

(解释)

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

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

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

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

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

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

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

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

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

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

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

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

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

(原文)

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

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

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

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

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

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

(解释)

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

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

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

又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,和教程文档中的使用方法不同。

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

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)

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

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

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)

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

pythonopencv算法_python opencv之SURF算法示例相关推荐

  1. pythonopencv算法_python opencv之分水岭算法示例

    本文介绍了python opencv之分水岭算法示例,分享给大家,具体如下: 目标 使用分水岭算法对基于标记的图像进行分割 使用函数cv2.watershed() 原理: 灰度图像可以被看成拓扑平面, ...

  2. python opencv入门 SURF算法(34)

    内容来自OpenCV-Python Tutorials 自己翻译整理 目标: SURF算法基础 opencv总SURF算法的使用 原理: 上节课使用了SIFT算法,当时这种算法效率不高,需要更快速的算 ...

  3. opencv之SURF算法原理及关键点检测

    1.概述 在基础篇里面讲模板匹配的时候已经介绍过,图像匹配主要有基于灰度和基于特征两种方法.基于特征匹配的方法有很多种如:FAST.HARRIS.SIFT.SURF.SUSAN等.其中SIFT算法由D ...

  4. OpenCV:SURF算法浅析

    引子: 课题需要SURF特征提取算法,在运动中提取摄像头图像中的特征点,并进行跟踪匹配,以此估计运动状态.开始找到了SIFT算法,SIFT特征提取具有极强的适应能力,但运算量稍大,后来就有了SURF特 ...

  5. python canny算法_Python 实现 Canny 边缘检测算法

    Canny 边缘检测算法由计算机科学家 John F. Canny 于 1986 年提出的.其不仅提供了算法,还带来了一套边缘检测的理论,分阶段的解释如何实现边缘检测.Canny 检测算法包含下面几个 ...

  6. python数圈算法_Python实现随机爬山算法

    随机爬山是一种优化算法.它利用随机性作为搜索过程的一部分.这使得该算法适用于非线性目标函数,而其他局部搜索算法不能很好地运行.它也是一种局部搜索算法,这意味着它修改了单个解决方案并搜索搜索空间的相对局 ...

  7. python实现排序算法_python实现各种排序算法

    冒泡排序 """ 分析 1. 算法是一种与语言无关的东西,更确切地说就算解决问题的思路,就是一个通用的思想的问题 2. 冒泡算法作为最简单的一种排序算法,我们的关注点不应 ...

  8. python车牌识别算法_python实现车牌识别的示例代码

    某天回家之时,听到有个朋友说起他正在做一个车牌识别的项目 于是对其定位车牌的位置算法颇有兴趣,今日有空得以研究,事实上车牌识别算是比较成熟的技术了, 这里我只是简单实现. 我的思路为: 对图片进行一些 ...

  9. python实现堆排序算法_Python实现的堆排序算法示例

    本文实例讲述了Python实现的堆排序算法.分享给大家供大家参考,具体如下: 堆排序的思想:堆是一种数据结构,可以将堆看作一棵完全二叉树,这棵二叉树满足,任何一个非叶节点的值都不大于(或不小于)其左右 ...

最新文章

  1. pandas索引复合索引dataframe数据、索引其中一个水平(level)的所特定数据行、指定数据行(index a row of a level)、使用元组tuple表达复合索引的指定行
  2. CCNP学习笔记2-路由部分--EIGRP
  3. PIC18F26K20
  4. maven下载,安装与eclipse中maven配置
  5. ENVI学习总结(七)——图像融合
  6. hashtable允许null键和值吗_HashMap 和 Hashtable 的 6 个区别,最后一个没几个人知道!...
  7. linux系统 锐捷_Client for RuiJie(锐捷客户端 for linux) 升级版
  8. 几款web富文本编辑器汇总整理
  9. Emmagee 2.5 在MUMU模拟器上启动后直接失败,换成夜神模拟器可以正常使用
  10. Vue中将十六进制颜色格式转换为RGB格式
  11. 计算机硬盘使用寿命,一块机械硬盘的寿命能超过十年吗?
  12. 8B/10B编码基本原理
  13. 和绅的女人们——汉人、黑人、白人、还有他的“干”女儿
  14. 降维 (Dimensionality Reduction)
  15. 【x与y的非线性关系】回归,自变量,自变量的平方项,自变量的二次项
  16. 高代|共轭矩阵 自共轭矩阵
  17. 模仿天天动听5可联网下载歌词的音乐播放器
  18. 粒子群算法matlab代码(注释很详细哦,图像也美美哒,任意维度)
  19. matlab描述统计分析步骤,MATLAB实现描述性统计分析的例子例题
  20. 大连27中学距离计算机学校多远,热烈祝贺大连市第二十四中学被中国计算机(CCF)学会授予首批NOI培训基地...

热门文章

  1. Android轮播图 banner,图片视频混播banner
  2. 微信小程序登录 更新中
  3. ftp 530 linux,Linux启动ftp服务器530 Permission denied解决方法
  4. jquery ajax post请求连续多个问号特殊数据异常问题
  5. jsencrypt加密同一值返回不同密文_密码学原语如何应用?解析密文同态性的妙用...
  6. eclipse中git解决冲突
  7. Android之Notification初识
  8. 2014全国计算机二级vfp模拟试题和答案,2014年全国计算机二级考试VF模拟试题
  9. java客户姓名添加和查找_java类与对象 演练 客户姓名添加与查看
  10. 【C++深度剖析教程40】使用数值型模板技术计算1+2+3+...+N的值