[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法

回顾,上节课你学了什么?

R=cv.cornerHarris(img,blockSize,ksize,k)

corners=cv.goodFeaturesToTrack(img,maxCorners,qualityLevel,minDistance)

array=矩阵.ravel()

矩阵.astype("int")

目录

SIFT

1.原理

2.步骤

【1】尺度空间极值检测:

【2】关键点定位(去除噪声点和边界点):

【3】关键点方向确定:

【4】关键点描述:

3.代码API

SURF

总结,这节课你学到了什么?


SIFT

1.原理

Harris和Shi-tomas具有旋转不变性但不具有尺度不变性,当图片缩放后角点数量会变化。

SIFT具有尺度不变性,实质是在不同尺度上检测特征点,并计算出特征点方向,SIFT查找的特征点突出,不会因为光照,仿射变换,噪声而发生变化

2.步骤

【1】尺度空间极值检测:

搜索所有尺度上的图像位置。通过高斯差分函数来识别潜在的对于尺度和旋转不变的关键点。

不同空间尺度下用不同的检测窗口,对于小关键点,用小窗口,大关键点用大窗口。

一个图像的尺度空间L(x,y,σ),定义为原始图像l(x,y)与一个可变尺度的2维高斯函数G(x,y,σ)(2维正态分布函数)卷积运算,即:

σ为标准差也称尺度空间,σ越大,图像越大尺度,越模糊。通过观察二维高斯函数,一般认为一个点上下左右3σ之内的像素起作用,所以高斯核大小为(6σ+1,6σ+1)就可以保证相关像素的影响,高斯核是唯一可以产生多尺度空间的核函数。

1.下面来构建高斯金字塔

(1)首先进行升采样,尽可能多保留原始图像信息

(2)逐步降采样(下采样),进行高斯模糊

几个模糊的图像构成一个Octave(一般为三个图像),下采样使得图片的长宽各缩小为原来一半,这个图像就是下一个Octave初始图像,依次完成整个八度构建完成金字塔构建。

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第1张图片

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第2张图片

 3.构建高斯差分金字塔

利用LoG(高斯拉普拉斯方法),即图像的二阶导数,可以在不同的尺度下检测图像的关键点信息,从而确定图像的特征点。但LoG的计算量大,效率低。所以我们通过两个相邻高斯尺度空间的图像的相减得到DoG(高斯差分)来近似LoG。

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第3张图片

 后续SIFT特征点都是在差分金字塔上获取的。

在差分金字塔上搜索局部最大值。对于图像中的一个像素点而言,它需要与自己周围的8邻域,以及尺度空间中,上下两层中的相邻的18 (2x9) 个点相比。如果是局部最大值,它就可能是一个关键点。基本.上来说关键点是图像在相应尺度空间中的最好代表。如下图所示:

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第4张图片

【2】关键点定位(去除噪声点和边界点):

由于噪声和边缘影响,还要进一步检验确定特征点。

尺度空间的泰勒级数展开,极值点小于阈值(contrastThreshold,一般为0.03或0.04)被忽略;

DoG算法对边界即为明显,Harris算法不仅可以角点检测,也可以进行边界检测,俩个特征值比值大于莫个阈值被忽略。

【3】关键点方向确定:

图像的关键点已经确定,为实现旋转不变性,基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。

对于任一关键点,我们采集其所在高斯金字塔图像,关键点为中心,以r为半径的区域内所有像素梯度特征(幅值和幅角) ,半径r为:

 梯度的幅值和方向公式:

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第5张图片

可视化举例

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第6张图片

 完成关键点梯度和幅度计算后,进行直方图统计,像素梯度的幅值根据举例中心像素位置,进行高斯加权,方差为1.5σ,再叠加到直方图的高度y上

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第7张图片

 分配给特征点一个主方向,一个或多个辅方向,再进行插值拟合得到曲线,得到更精确的角度

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第8张图片

 主方向为直方图最高值方向,辅方向直方图高度为主方向的80%-100%

获得图像关键点主方向后,每个关键点有三个信息(x,y,σ,θ):位置x,y、尺度σ、方向θ。由此我们可以确定一个SIFT特征区域。通常使用一个带箭头的圆或直接使用箭头表示SIFT区域的三个值:中心表示特征点位置,半径表示关键点尺度,箭头表示方向。如下图所示:

 [图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第9张图片

【4】关键点描述:

在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度作为关键点的描述符,它允许比较大的局部形状的变形、光照变化、视角变化。描述符不仅具有关键点,还包括周围有贡献的点,具有可区分性。

主要思路就是通过将关键点周围图像区域分块d x d个子区域(d一般取4),每个区域大小为(3σ,3σ),考虑需要进行三次线性插值,特征点领域总大小为(3σ(d+1),3σ(d+1))

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第10张图片

为保持旋转不变性,以特征点为中心,将坐标轴旋转到主方向的方向上

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第11张图片

计算小区域d x d个小区域,每个小区域(3σ,3σ)的梯度直方图,σ=0.5高斯加权,生成具有特征向量,插值计算八方向个梯度,对图像信息进行抽象。

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第12张图片

每个种子点,会落在四个区域之间,最终累加的梯度大小为:

其中k,m, n为0或为1。如上统计4*4*8 = 128个梯度信息即为该关键点的特征向量,按照特征点的对每个关键点的特征向量进行排序,就得到了SIFT特征描述向量。

3.代码API

#实例化sift

sift=cv.SIFT_create()                         (最新版本opencv)

sift=cv.xfeatures2d.SIFT_create()       (低版本)

#检测关键点并计算

kp,des=sift.detectAndCompute(gray,None)

kp:关键点信息,每个点(x,y,σ,θ):位置x,y、尺度σ、方向θ

des:描述符信息,128个梯度信息即为该关键点的特征向量

sift:上一步实例化的sift

gray:灰度图像

#将关键点绘制在图像上

cv.drawKeypoints(image,keypoints,outputimage,color,flags)

image:原始图像

keypoints:关键点信息

outputimage:输出图像

color:绘制颜色

flags:

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第13张图片

举例:

#9.1

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
#解决中文显示问题,固定格式,直接复制下面俩行代码就行
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

#1.读取灰度图像
pic1 =cv.imread("10.jpg")
gray=cv.cvtColor(pic1,cv.COLOR_BGR2GRAY)
#2.SIFT实例化
sift=cv.SIFT_create()
#3.检测关键点
kq,dst=sift.detectAndCompute(gray,None)
#4.绘制关键点
pic2=pic1.copy()
cv.drawKeypoints(pic2,kq,pic2,(0,0,255),cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)#flags=4可以替换cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
#绘制图像
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,10))
axes[0,0].set_title("原图")
axes[0,0].imshow(pic1[:,:,::-1])
axes[0,1].set_title("灰度图")
axes[0,1].imshow(gray,plt.cm.gray)
axes[1,1].set_title("SIFT特征点检测")
axes[1,1].imshow(pic2[:,:,::-1])

plt.show()
cv.waitKey(0)

结果

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第14张图片

SURF

代码API和上述SIFT算法一样,就是更换名称就行

3.4版本之后因专利版权问题移除了SIFT/SURF的相关库,因此在使用较新版本的cv库时会报错,好消息是2020年3月17日之后一代传奇算法SIFT专利到期了,但是SURF还是受版权保护。相关消息更改见以下博客,选择适合的第三方库OpenCV低版本就可以使用:

【OpenCV】2020年关于SIFT算法专利版权问题的解决办法_四季豆炒饭的博客-CSDN博客_opencv专利OpenCV 3.4之后因专利版权问题移除了SIFT/SURF的相关库,因此在使用较新版本的cv库时会报错https://blog.csdn.net/cleanlii/article/details/109561089?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166467877116800186567077%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166467877116800186567077&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-109561089-null-null.142%5Ev51%5Econtrol_1,201%5Ev3%5Econtrol_1&utm_term=opencv%E5%BA%93%E5%A4%9A%E5%B0%91%E7%89%88%E6%9C%ACSURF%E5%8F%97%E7%89%88%E6%9D%83%E4%BF%9D%E6%8A%A4&spm=1018.2226.3001.4187

SURF(加速版的具有鲁棒性的特征,SpeededUp Robust Features),SURF是尺度不变特征变换算法(SIFT算法)的加速版。SURF最大的特征在于采用了harr特征以及积分图像的概念。,计算更小小,运算速度更快。区别如下

[图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_第15张图片

OpenCV系列之SURF简介(加速的强大功能)| 四十_woshicver的博客-CSDN博客目标在这一章当中,我们将了解SURF的基础我们将在OpenCV中看到SURF函数理论在上一章中,我们看到了SIFT用于关键点检测和描述符。但相对缓慢,人...https://blog.csdn.net/woshicver/article/details/105140920?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166467664416800180610199%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166467664416800180610199&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-105140920-null-null.142%5Ev51%5Econtrol_1,201%5Ev3%5Econtrol_1&utm_term=opencv%20SURF&spm=1018.2226.3001.4187

总结,这节课你学到了什么?

#实例化sift

sift=cv.SIFT_create()  

#检测关键点并计算

kp,des=sift.detectAndCompute(gray,None)

#将关键点绘制在图像上

cv.drawKeypoints(image,keypoints,outputimage,color,flags)

你可能感兴趣的:(黑马python图像识别笔记,算法,opencv,计算机视觉,图像处理,人工智能)