Java教程

图像特征-SIFT

本文主要是介绍图像特征-SIFT,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

图像特征-SIFT

概念

SIFT:即恒定尺度特征变换(Scale Invariant Feature Transform)
作用:从图像中提取关键点,再从每个关键点中提取特征向量

提取关键点

图像尺度空间

概念:考虑图像在不同的尺度下都存在的特点,使得机器对物体在不同尺度下有一个统一的认知

方法:尺度空间的获取通常使用高斯模糊来实现

\[L(x,y,\sigma)=G(x,y,\sigma)*I(x,y) \\其中,I是某分辨率下(大小)的图像,G是高斯函数,L是得到的尺度空间 \\G(x,y,\sigma)=\frac{1}{2\pi\sigma ^{2}}e^{\frac{x^{2}+y^{2}}{2\sigma ^{2}}} \]

5x5的高斯核:

不同\(\sigma\)的高斯函数决定了对图像的平滑程度,越大的\(\sigma\)值对应的图像越模糊(\(\sigma\)值越大权重越不集中)

图像金字塔

多分辨率金字塔:自底向上图像分辨率逐层减小

多分辨率金字塔的每一层在不同的高斯核下可以得到多个不同模糊程度的图像

高斯差分金字塔(DOG,Difference of Gaussian):由将同层的相邻不同模糊程度的图像相减得到,所以若某一层有n种程度的模糊图像,则有n-2种差分图像(除去最顶和最底层)

DOG定义公式:

\[D(x,y,\sigma)=[G(x,y,k\sigma)-G(x,y,\sigma)]*I(x,y)=L(x,y,k\sigma)-L(x,y,\sigma) \]

DOG空间极值检测

为了寻找尺度空间的极值点,每个像素点要和其图像域(同一尺度空间)和尺度域(相邻的尺度空间)的所有相邻点进行比较,当其大于(或者小于)所有相邻点时,该点就是极值点。如下图所示,中间的检测点要和其所在图像的3×3邻域8个像素点,以及其相邻的上下两层的3×3领域18个像素点,共26个像素点进行比较。

关键点的精确定位

上一步得到的是DOG空间的局部极值点,而且均是离散的点,为了进一步精确得到关键点,可以对各个极值点的尺度空间DOG函数进行曲线拟合,再计算曲线的极值以代替原来的极值点

方法:可以使用泰勒展开进行对每个极值点的尺度空间分别进行拟合

以一元函数为例,展开至二阶导:

\[f(x)\approx f(0)+f'(0)x+\frac{f''(0)}{2}x^{2} \\运用差分,有 \\f'(0)\approx \frac{f(1)-f(-1)}{2} \\f''(0)\approx f(1)+f(-1)-2f(0) \]

推至三维空间,并向量化表达:

\[D(\Delta x, \Delta y,\Delta \sigma)=D(x,y,\sigma)+\begin{bmatrix}\frac{\partial D}{\partial x} & \frac{\partial D}{\partial y} & \frac{\partial D}{\partial \sigma} \\\end{bmatrix}\begin{bmatrix}\Delta x \\\Delta y \\\Delta \sigma \end{bmatrix}+\frac{1}{2}\begin{bmatrix}\Delta x & \Delta y & \Delta \sigma \\\end{bmatrix}\begin{bmatrix}\frac{\partial^2 D}{\partial x^2} & \frac{\partial^2 D}{\partial x \partial y} & \frac{\partial^2 D}{\partial x \partial \sigma} \\\frac{\partial^2 D}{\partial y \partial x} & \frac{\partial^2 D}{\partial y^2} & \frac{\partial^2 D}{\partial y \partial \sigma} \\\frac{\partial^2 D}{\partial \sigma \partial x} & \frac{\partial^2 D}{\partial \sigma \partial y} & \frac{\partial^2 D}{\partial \sigma ^2} \\\end{bmatrix}\begin{bmatrix}\Delta x \\\Delta y \\\Delta \sigma \end{bmatrix} \\简便起见,写为D(x)=D+\frac{\partial D^{T}}{\partial x}\Delta x+\frac{1}{2}\Delta x^{T}\frac{\partial^2 D^{T}}{\partial x^2}\Delta x \\即当x=-\frac{\partial^2 D^{T}}{\partial x^2}\frac{\partial D^{T}}{\partial x}时取得极值 \]

消去边界响应

运用Hessian矩阵:

\[H(x,y)=\begin{bmatrix}D_{xx}(x,y) & D_{xy}(x.y) \\D_{xy}(x,y) & D_{yy}(x,y) \\\end{bmatrix} \\Tr(H)=D_{xx}+D_{yy}=\alpha+\beta \\Det(H)=D_{xx}D_{yy}-(D_{xy})^{2}=\alpha\beta \\\frac{Tr(H)}{Det(H)}=\frac{(\alpha+\beta)^{2}}{\alpha\beta}=\frac{(\gamma + 1)^{2}}{\gamma} \\Lowe在论文中给出的阈值为\gamma=10,也就是说对于主曲率比值大于10的特征点将被删除 \\从另一角度理解: \\矩阵H是个实对称矩阵,可以像harris那样转成对角阵 \\对应得到\lambda max和\lambda min,这\lambda max和\lambda min对应就是上述的\alpha和\beta \\仔细观察之前\gamma,发现\gamma=\frac{\alpha}{\beta}=\frac{\lambda max}{\lambda min} \\即当\frac{\lambda max}{\lambda min}大于10时判定为边界,进行删除,与harris的概念相符合 \]

从关键点中提取关键向量

特征点的主方向

目标:得到特征点的位置(x,y)、梯度的模m、梯度的方向\(\theta\)

对于给定的点(x,y),可知它的尺度空间值L(x,y)
运用差分的思想,有:

\[\frac{\partial L}{\partial x}\approx \frac{1}{2}(L(x+1,y)-L(x-1,y)) \\\frac{\partial L}{\partial y}\approx \frac{1}{2}(L(x,y+1)-L(x,y-1)) \\\; \\\therefore \triangledown L=\frac{\partial L}{\partial x}\overrightarrow{i}+\frac{\partial L}{\partial y}\overrightarrow{j} \\\approx \frac{1}{2}(L(x+1,y)-L(x-1,y))\overrightarrow{i}+\frac{1}{2}(L(x,y+1)-L(x,y-1))\overrightarrow{j} \\\; \\\therefore m(x,y)=\left|\triangledown L \right| \\\approx \frac{1}{2}\sqrt{[L(x+1,y)-L(x-1,y)]^{2}+[L(x,y+1)-L(x,y-1)]^{2}} \\\theta (x,y)\approx arctan\frac{L(x,y+1)-L(x,y-1)}{L(x+1,y)-L(x-1,y)} \]

每个特征点可以得到三个信息(x,y,σ,θ),即位置、尺度和方向。具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等,但是方向不同的特征点。

生成特征描述

概念:在完成关键点的梯度计算后,使用直方图统计关键点邻域内像素的梯度和方向。

为了保证特征矢量的旋转不变性,要以关键点为中心,在附近邻域内将坐标轴旋转θ角度,即将坐标轴旋转为关键点的主特征方向。

使用的变换矩阵为:

\[\begin{bmatrix}x' \\y'\end{bmatrix}=\begin{bmatrix}cos\theta & -sin\theta \\sin\theta & cos\theta \\\end{bmatrix}\begin{bmatrix}x \\y\end{bmatrix} \]

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

论文中建议对每个关键点,以4x4为一个种子点,共16个种子点来描述,这样一个关键点就会产生128维的SIFT特征向量。

OpenCV中的使用

sift = cv2.xfeatures2d.SIFT_create()
  • 作用:创建SIFT对象
  • sift:返回的SIFT对象
kp = sift.detect(gray, None)
  • 作用:从灰度图中提取关键点
  • gray:灰度图
  • kp:得到的灰度图中的关键点
img = cv2.drawKeypoints(gray, kp, img)
  • 作用:将关键点在灰度图gray上画出来
  • gray:灰度图
  • img:画完关键点后的输出图
kp, des = sift.compute(gray, kp)
  • 作用:从关键点中提取关键向量
  • kp:关键点
  • gray:关键点对应的灰度图
  • des:得到的特征向量,其shape是(n, 128),其中n是关键点的数量

使用例:

import cv2
import numpy as np

# 读入图片,并转灰度图
img = cv2.imread('test_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('drawKeypoints', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 计算特征向量集,输出特征向量集des的shape
kp, des = sift.compute(gray, kp)
print (np.array(kp).shape)
这篇关于图像特征-SIFT的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!