OpenCV计算机视觉实战(Python)| 12、SIFT图像特征

简介

本节为《OpenCV计算机视觉实战(Python)》版第12讲,SIFT图形特征,的总结。

总结

1. SIFT介绍

SIFT全称:Scale Invariant Feature Transform

首先介绍图像尺度空间的定义。

图像尺度空间

在一定的范围内,无论物体是大还是小,人眼都可以分辨出来,然而计算机要有相同的能力却很难,所以要让机器能够对物体在不同尺度下有一个统一的认知,就需要考虑图像在不同的尺度下都存在的特点。

尺度空间的获取通常使用高斯模型来实现:
在这里插入图片描述
其中,GG是高斯函数。
在这里插入图片描述
如图所示:
在这里插入图片描述
\sigma 参数,控制的是核模糊的程度。不同的\sigma的高斯函数决定了图像的平滑程度,越大的\sigma值对应的图像越模糊。

多分辨率金字塔

尺度空间->金字塔

每一个金字塔都能做多分辨率特征,因此可以获得多分辨率金字塔。
在这里插入图片描述

高斯差分金字塔(DOG)

金字塔->高斯差分金字塔

如果每一层特征差异不大,那么意义不大;如果两层之间特征差异比较大,那么这个差异性结果可以作为一个有用的信息。
在这里插入图片描述
DOG数学定义:
在这里插入图片描述
该公式需要三个参数:位置:(x,y),高斯模糊参数\sigma。

找到极值点

将第二层的中间点,与同一层的8个临近点,和上层和下层的9个临近点(总共是26个点)做比较,得到极值点(极大值和极小值)f。

可以看出,第一层和最后一层是没有办法做DOG运算的。
在这里插入图片描述
DOG得到的值是一系列离散的点。

离散点需要拟合成真实的点。

关键点的精确定位

离散DOG值->拟合

这些候选关键点是DOG空间的局部极值点,而且这些极值点均为离散的点,精确定位极值点的一种方法是,对尺度空间DOG函数进行曲线拟合,计算其极值点,从而实现关键点的精确定位。

在这里插入图片描述
三维的数学公式:
在这里插入图片描述
从这个公式中可以对极值点进行修正,得到真正精确的极值点。

消除边界相应

极值点->消除边界相应

Hessian矩阵:
在这里插入图片描述
Hessian矩阵的特征值为R1,R2,当R1、R2差别过大的时候为边界。
论文中给出的R1/R2的比值为10,认为比值大于10的为边界。

得到关键点后,如何让计算机认识关键点?
将关键点转换为数值!

在后续的改进中,消除的相应更多,不止边界相应。

特征点的主方向

关键点->数值表示的关键点

每个点L(x,y)的梯度的模m(x,y)以及方向theta(x,y):
在这里插入图片描述
需要位置、尺度和方向,三个特征。
每个特征点可以得到三个信息(x,y,sigma, theta),也就是位置、尺度和方向。具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等,但是方向不同的特征点。

生成特征描述

在完成关键点的梯度计算后,使用直方图统计邻域内像素的梯度和方向(只统计了8个方向)。
主方向:最高
次方向:第二高
相当于两个特征向量。
在这里插入图片描述
为了保证矢量的旋转不变形,要以特征点为中心,在附近邻域内将坐标旋转theta角度,即将坐标轴旋转为特征点的主方向。

在这里插入图片描述
旋转:保证特征具有不变形

构造特征

旋转之后的主方向为中心去88的窗口,求每个像素的梯度幅值和方向。
箭头方向代表梯度方向,长度代表梯度幅值,然后利用高斯窗口对其进行加权运算。
最后在每个4
4的小块上绘制8个方向的梯度直方图,计算每个梯度方向的累加值,即可形成一个种子点,即每个特征的由4个种子点组成,每个种子点有8个方向的向量信息。

在这里插入图片描述
论文中建议对每个关键点使用4*4共16个种子点来描述,这样一个关键点就会产生128组的SIFT特征向量
在这里插入图片描述
通常写为:(4,4,8)

2. OpenCV程序

OpenCV的版本,3.4.3以上的版本,存在专利保护现象,因此如果调用OpenCV的SIFT函数的话,需要将版本降到3.4.3以下。

程序给出的OpenCV版本为:3.4.1

import cv2

img = cv2.imread('test.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 得到特征点
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(gray, None)  # kp就表示关键点,封装好的类型

img = cv2.drawKeypoints(gray, kp, img)  # 绘制关键点
cv2.imshow('drawKeypoints', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 计算特征
kp, des = sift.compute(gray, kp)
print(np.array(kp).shape)  # (6827,)
print(des.shape)  # (6827,128)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值