图像特征-SIFT

图像特征-SIFT

概念

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

提取关键点

图像尺度空间

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

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

L(x,y,σ)=G(x,y,σ)I(x,y)IGLG(x,y,σ)=12πσ2ex2+y22σ2

5x5的高斯核:

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

图像金字塔

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

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

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

DOG定义公式:

D(x,y,σ)=[G(x,y,kσ)G(x,y,σ)]I(x,y)=L(x,y,kσ)L(x,y,σ)

DOG空间极值检测

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

关键点的精确定位

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

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

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

f(x)f(0)+f(0)x+f(0)2x2f(0)f(1)f(1)2f(0)f(1)+f(1)2f(0)

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

D(Δx,Δy,Δσ)=D(x,y,σ)+[DxDyDσ][ΔxΔyΔσ]+12[ΔxΔyΔσ][2Dx22Dxy2Dxσ2Dyx2Dy22Dyσ2Dσx2Dσy2Dσ2][ΔxΔyΔσ]便D(x)=D+DTxΔx+12ΔxT2DTx2Δxx=2DTx2DTx

消去边界响应

运用Hessian矩阵:

H(x,y)=[Dxx(x,y)Dxy(x.y)Dxy(x,y)Dyy(x,y)]Tr(H)=Dxx+Dyy=α+βDet(H)=DxxDyy(Dxy)2=αβTr(H)Det(H)=(α+β)2αβ=(γ+1)2γLoweγ=1010Hharrisλmaxλminλmaxλminαβγγ=αβ=λmaxλminλmaxλmin10harris

从关键点中提取关键向量

特征点的主方向

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

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

Lx12(L(x+1,y)L(x1,y))Ly12(L(x,y+1)L(x,y1))L=Lxi+Lyj12(L(x+1,y)L(x1,y))i+12(L(x,y+1)L(x,y1))jm(x,y)=|L|12[L(x+1,y)L(x1,y)]2+[L(x,y+1)L(x,y1)]2θ(x,y)arctanL(x,y+1)L(x,y1)L(x+1,y)L(x1,y)

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

生成特征描述

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

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

使用的变换矩阵为:

[xy]=[cosθsinθsinθcosθ][xy]

旋转之后以主方向为中心取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)
posted @   kksk43  阅读(229)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
特效
黑夜
侧边栏隐藏
点击右上角即可分享
微信分享提示