图像处理:局部描述子SIFT算法

目录

0、关于SIFT的介绍

1、兴趣点

2、描述子 

SIFT算法实现

1.实例化sift

2.利用sift.detectAndCompute()检测关键点并计算

3.将关键点检测结果绘制在图像上

Opencv实现

总结


0、关于SIFT的介绍

SIFT,即尺度不变特征变换,一种局部特征描述子,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。SIFT特征包括兴趣点检测器和描述子。SIFT描述子具有非常强的稳健性,这在很大程度上也是SIFT特征能够成功和流行的主要原因。自从SIFT出现后,许多与他本质上使用相同描述子的方法也相继出现。现在,SIFT描述符常和许多不同的兴趣点检测器相结合,有时甚至在整幅图像上密集使用。SIFT特征对于尺度、旋转和亮度都具有不变性,因此,它可以用于三维视角和噪声的可靠匹配。

1、兴趣点

高斯核是唯一可以产生多尺度空间的核函数——《Scale-space theory:A basic tool for analysing structures at different scales》

SIFT是采用高斯差分函数来定位兴趣点:

              D(x,\sigma )=[G{\underset{k\sigma}{}}(x)-G{\underset{\sigma}{}}(x)]*\mathit{I}(x))=[G{\underset{k\sigma}{}}-G{\underset{\sigma}{}}]*\mathit{I}=\mathit{I{\underset{k\sigma}{}}-}\mathit{I{\underset{\sigma}{}}}

其中:

sigma为尺度空间因子,它决定了图像的模糊的程度。大尺度表现得是图像得概貌信息,小尺度表现得是图像得细节信息。

G{\underset{\sigma}{}}是指二维的高斯核,也就是G(x,y)=\frac{1}{2\pi\sigma ^{2} }\mathrm{e}^{-\frac{(\mathit{x^{2}}+\mathit{y^{2}})}{2\sigma ^{2}}}大家对于它应该还是比较熟悉吧;

\mathit{I{\underset{\sigma}{}}}是使用G{\underset{\sigma}{}}模糊的灰度图像;

k是决定相差尺度的常数。

兴趣点是在图像位置和尺度变化下 D(x,σ) 的最大值和最小值点。这些候选位置点通过滤波去除不稳定点。基于一些准则,比如认为低对比度和位于边上的点不是兴趣点,这样可以去除一些候选的兴趣点。

2、描述子 

        上面讨论的兴趣点(关键点)位置描述子给出了兴趣点的位置和尺度信息。为了实现旋转不变性,基于每个点周围图像梯度的方向和大小,SIFT 描述子又引入了参考方向。SIFT 描述子使用主方向描述参考方向。主方向使用方向直方图(以大小为权重)来度量。

        下面我们基于位置、尺度和方向信息来计算描述子。为了对图像亮度具有稳健性,SIFT 描述子使用图像梯度。下图所示为描述子的构造过程。

图像处理:局部描述子SIFT算法_第1张图片

        SIFT描述子会以每个像素点附近选取一个网格(标准为4*4),在每个子区域当中计算梯度方向直方图,每个子区域拼接起来组成描述子向量,而每个子区域的直方图拼接起来组成描述子向量,每个子区域使用 8 个小区间的方向直方图,会产生共128 个小区间的直方图(4×4×8=128)。

图解:

  (a)  一个围绕兴趣点的网格结构,其中该网格已经按照梯度主方向进行旋转

  (b)  在网格的一个子区域内构造梯度方向的8-bin直方图

  (c)  在网格的每个子区域内提取直方图

  (d)  拼接直方图,得到一个长的特征向量

SIFT算法实现

1.实例化sift

sift = cv2.xfeatures2d.SIFT_create()

2.利用sift.detectAndCompute()检测关键点并计算

kq, dst = sift.detectAndCompute(gray, None)

参数:

  • gray:进行关键点检测的图像,注意要是灰度图像

返回:

  • kp:关键点信息,包括位置,尺度,方向信息
  • des:关键点描述符,每个关键点对应128个梯度信息的特征向量

3.将关键点检测结果绘制在图像上

cv2.drawKeypoints(pic2, kq, pic2, (0, 0, 255),

参数:

image:原始图像

keypoints:关键点信息,将其绘制在图像上

outputimage:输出图片,可以是原始图像

color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。

flags:绘图功能的标识设置

  1. cv2.DRAW_MATCHES_FLAGS_DEFAULT:创建输出图像矩阵,使用现存的输出图像匹配对和特征点,对每一个关键点,对每一个关键点只绘制中间点.
  2. cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:不创建输出图像矩阵,而是在输出图像上绘制匹配对。
  3. cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:对每一个特征点绘制带大小和方向的关键点图形。
  4. cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制。

Opencv实现

import cv2
import matplotlib.pyplot as plt

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

图像处理:局部描述子SIFT算法_第2张图片

 

注:代码来源于黑马教程以及ζั͡ ั͡雾 ั͡狼 ั͡✾的博客(26条消息) [图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客_opencv sift目标检测

这里还有保姆级的,大家感兴趣的可以去学习,我只是作为了解。

(1条消息) Python实现SIFT算法,附详细公式推导和代码_Derle3er的博客-CSDN博客_python sift

总结

SIFT在图像的不变特征提取拥有无与伦比的优势,但并不完美,仍然存在实时性不高,有时特征点较少,对边缘光滑的目标无法准确提取特征点等缺陷。

你可能感兴趣的:(图像处理,算法,图像处理,人工智能)