目录
0、关于SIFT的介绍
1、兴趣点
2、描述子
SIFT算法实现
1.实例化sift
2.利用sift.detectAndCompute()检测关键点并计算
3.将关键点检测结果绘制在图像上
Opencv实现
总结
SIFT,即尺度不变特征变换,一种局部特征描述子,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。SIFT特征包括兴趣点检测器和描述子。SIFT描述子具有非常强的稳健性,这在很大程度上也是SIFT特征能够成功和流行的主要原因。自从SIFT出现后,许多与他本质上使用相同描述子的方法也相继出现。现在,SIFT描述符常和许多不同的兴趣点检测器相结合,有时甚至在整幅图像上密集使用。SIFT特征对于尺度、旋转和亮度都具有不变性,因此,它可以用于三维视角和噪声的可靠匹配。
高斯核是唯一可以产生多尺度空间的核函数——《Scale-space theory:A basic tool for analysing structures at different scales》
SIFT是采用高斯差分函数来定位兴趣点:
其中:
sigma为尺度空间因子,它决定了图像的模糊的程度。大尺度表现得是图像得概貌信息,小尺度表现得是图像得细节信息。
是使用模糊的灰度图像;
k是决定相差尺度的常数。
兴趣点是在图像位置和尺度变化下 D(x,σ) 的最大值和最小值点。这些候选位置点通过滤波去除不稳定点。基于一些准则,比如认为低对比度和位于边上的点不是兴趣点,这样可以去除一些候选的兴趣点。
上面讨论的兴趣点(关键点)位置描述子给出了兴趣点的位置和尺度信息。为了实现旋转不变性,基于每个点周围图像梯度的方向和大小,SIFT 描述子又引入了参考方向。SIFT 描述子使用主方向描述参考方向。主方向使用方向直方图(以大小为权重)来度量。
下面我们基于位置、尺度和方向信息来计算描述子。为了对图像亮度具有稳健性,SIFT 描述子使用图像梯度。下图所示为描述子的构造过程。
SIFT描述子会以每个像素点附近选取一个网格(标准为4*4),在每个子区域当中计算梯度方向直方图,每个子区域拼接起来组成描述子向量,而每个子区域的直方图拼接起来组成描述子向量,每个子区域使用 8 个小区间的方向直方图,会产生共128 个小区间的直方图(4×4×8=128)。
图解:
(a) 一个围绕兴趣点的网格结构,其中该网格已经按照梯度主方向进行旋转
(b) 在网格的一个子区域内构造梯度方向的8-bin直方图
(c) 在网格的每个子区域内提取直方图
(d) 拼接直方图,得到一个长的特征向量
sift = cv2.xfeatures2d.SIFT_create()
kq, dst = sift.detectAndCompute(gray, None)
参数:
返回:
cv2.drawKeypoints(pic2, kq, pic2, (0, 0, 255),
参数:
image:原始图像
keypoints:关键点信息,将其绘制在图像上
outputimage:输出图片,可以是原始图像
color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
flags:绘图功能的标识设置
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)
注:代码来源于黑马教程以及ζั͡ ั͡雾 ั͡狼 ั͡✾的博客(26条消息) [图像识别]10.OpenCV的特征点检测 SIFT和SURF算法_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客_opencv sift目标检测
这里还有保姆级的,大家感兴趣的可以去学习,我只是作为了解。
(1条消息) Python实现SIFT算法,附详细公式推导和代码_Derle3er的博客-CSDN博客_python sift
SIFT在图像的不变特征提取拥有无与伦比的优势,但并不完美,仍然存在实时性不高,有时特征点较少,对边缘光滑的目标无法准确提取特征点等缺陷。