详解SIFT、SURF和ORB特征点检测和描述算法

文章目录

  • 0 引言
  • 1 SIFT算法
    • 1.1 主要目的
    • 1.2 主要步骤
    • 1.3 示例代码
  • 2 SURF算法
    • 2.1 主要目的
    • 2.2 主要步骤
    • 2.3 示例代码
  • 3 ORB算法
    • 3.1 主要步骤
    • 3.2 代码示例
  • 4 三者对比

0 引言

本文主要对SIFTSURFORB特征点检测和描述算法进行详细的学习和比较。

⚠️ ⚠️ ⚠️ :SIFT、SURF是有专利保护的算法,在 opencv-contrib-python=3.4.3之后专利收费,可用anaconda创建一个临时环境,安装指定版本来测试:pip install opencv-contrib-python==3.4.2.17

1 SIFT算法

SIFT (Scale-Invariant Feature Transform) 是一种计算机视觉算法,用于检测和描述图像中的局部特征。SIFT 算法由 David Lowe1999 年提出,并在 2004年的论文中详细描述。

1.1 主要目的

SIFT 算法的主要目标是提取图像中的关键点,这些关键点在不同尺度和旋转下都具有不变性。它在图像中寻找具有稳定特征的局部极值点,并计算这些关键点的描述子。这些描述子可以用于在不同图像之间进行特征匹配,从而实现图像识别、目标跟踪等应用。

1.2 主要步骤

SIFT 算法的主要步骤如下:

  1. 尺度空间极值检测(Scale-space extrema detection):通过在图像的不同尺度上应用高斯差分Gaussian difference-of-Gaussian)进行滤波,检测图像中的极值点。这些极值点通常对应于图像中的边缘、角点等关键位置。

  2. 关键点定位(Keypoint localization):通过在尺度空间中对极值点进行精确定位,排除低对比度和边缘响应不明确的关键点。SIFT 算法使用了尺度空间的极值点的曲率来过滤掉不稳定的关键点。

  3. 方向分配(Orientation assignment):为每个关键点分配一个主方向,用于后续计算关键点的描述子。这样可以使描述子对旋转变换具有不变性。

  4. 关键点描述(Descriptor computation):根据关键点的尺度和方向,计算关键点周围区域的描述子。描述子通常使用关键点周围的梯度方向直方图表示,具有一定的独特性和不变性。

1.3 示例代码

由于OpenCV库中已经有对应的SIFT算法接口,直接调用即可,如下python代码:

import cv2

# 加载图像
image = cv2.imread('liuyf.jpg')
# 创建 SIFT 对象
sift = cv2.xfeatures2d.SIFT_create()
# 检测关键点和计算描述子
keypoints, descriptors = sift.detectAndCompute(image, None)
# 绘制关键点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)
# 保存图像
cv2.imwrite('image_with_sift.jpg', image_with_keypoints)
# 显示图像
cv2.imshow('Image with Keypoints', image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中输入左图,输出右图,主要调用了cv2.xfeatures2d.SIFT_create()创建SIFT对象,然后调用sift.detectAndCompute(image, None)检测关键点和计算描述子。

详解SIFT、SURF和ORB特征点检测和描述算法_第1张图片 详解SIFT、SURF和ORB特征点检测和描述算法_第2张图片

SIFT 算法的主要优点是其对尺度、旋转、仿射变换等具有较好的不变性,使得它在图像匹配、目标识别和三维重建等领域具有广泛的应用。然而,SIFT 算法计算量较大,不适用于实时应用,后续也出现了一些更快的替代算法,如SURFSpeeded Up Robust Features)和ORBOriented FAST and Rotated BRIEF)。

2 SURF算法

SURF (Speeded Up Robust Features) 是一种基于 SIFT 算法的改进版本,它在计算效率和描述子的稳健性方面进行了优化。SURF 算法由 Herbert Bay 等人于 2006 年提出,并发表 SURF论文。

2.1 主要目的

SIFT 算法相比,SURF 算法主要改进了以下两个方面:

  1. 尺度空间极值检测:SURF 算法使用快速Hessian矩阵(Fast Hessian)来检测图像中的尺度空间极值点。相比之下,SIFT 算法使用高斯差分金字塔来检测极值点,而快速Hessian矩阵能够更快地计算图像的尺度空间。

  2. 描述子计算:SURF 算法使用了一种加速技术称为积分图像(Integral Image),用于快速计算关键点周围区域的梯度和特征描述子。这种技术可以显著加快计算速度。

由于 SURF 算法对尺度、旋转和仿射变换具有较好的不变性,并且计算速度更快,因此在实际应用中得到了广泛的应用。与 SIFT 算法相比,SURF 算法在实时性要求较高的场景下更加适用

2.2 主要步骤

SURF算法的主要步骤可以概括为以下几个阶段:

  1. 尺度空间构建:首先,对输入图像进行尺度空间构建。这通常涉及使用高斯滤波器构建图像的金字塔,通过不同尺度的图像来检测不同尺度的特征。

  2. 关键点检测:在每个尺度的图像中,使用Hessian矩阵计算特征点的兴趣值。Hessian矩阵描述了图像局部区域的灰度变化情况,通过检测局部最大值或最小值来确定关键点。

  3. 关键点定位:通过在尺度空间中插值,精确定位关键点的位置。这样做是为了提高关键点的精度,并且能够在亚像素级别进行定位。

  4. 方向分配:对于每个关键点,计算其主要方向。这通常通过计算特征点周围区域的梯度方向直方图来实现。主要方向用于后续的描述子计算和旋转不变性。

  5. 描述子计算:在关键点周围的邻域中,计算描述子来描述关键点的特征。SURF算法使用了一种基于哈尔小波响应的描述子计算方法。描述子捕捉了关键点周围区域的局部特征。

  6. 特征匹配:使用描述子比较来进行特征匹配。常见的方法是使用距离度量(如欧氏距离或汉明距离)来衡量描述子之间的相似性。匹配算法可以采用暴力匹配或更高级的方法(如最近邻搜索或KD树)。

  7. 异常值剔除:在进行特征匹配后,可能存在一些错误的匹配或异常值。通过应用一些筛选机制(如RANSAC算法)来剔除这些异常值,以获得更准确的匹配结果。

2.3 示例代码

由于OpenCV库中已经有对应的SURF算法接口,直接调用即可,如下python代码:

import cv2

# 加载图像
image = cv2.imread('liuyf.jpg')
# 创建 SURF 对象
surf = cv2.xfeatures2d.SURF_create()
# 检测关键点和计算描述子
keypoints, descriptors = surf.detectAndCompute(image, None)
# 绘制关键点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)
# 保存图像
cv2.imwrite('image_with_surf.jpg', image_with_keypoints)
# 显示图像
cv2.imshow('Image with Keypoints', image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中输入左图,输出右图,主要调用了cv2.xfeatures2d.SURF_create()创建SIFT对象,然后调用surf.detectAndCompute(image, None)检测关键点和计算描述子。

详解SIFT、SURF和ORB特征点检测和描述算法_第3张图片 详解SIFT、SURF和ORB特征点检测和描述算法_第4张图片

3 ORB算法

ORBOriented FAST and Rotated BRIEF)也是一种目前常用的计算机视觉算法,用于图像特征提取和描述。它是在FAST角点检测器和BRIEF描述子算法的基础上进行改进的。 ORB论文

详细的实现版本也可参考如下的ORB-SLAM2中的ORBextractor

ORB-SLAM2算法8之特征点提取、生成描述子的ORBextractor

3.1 主要步骤

`ORB算法的主要步骤如下:

  1. FAST角点检测:使用FASTFeatures from Accelerated Segment Test)算法检测图像中的角点。FAST算法通过比较像素点与其周围邻域像素的灰度值来判断是否为角点。

  2. 构建金字塔:为了对不同尺度下的图像进行处理,ORB算法使用图像金字塔。通过对原始图像进行不断的降采样,得到一系列尺度不同的图像。

  3. 计算角点的方向:为了提取具有旋转不变性的特征,ORB算法使用灰度质心法来计算角点的方向。它计算角点周围像素的灰度质心,然后根据质心的位置计算角点的方向。

  4. 构建BRIEF描述子:使用BRIEFBinary Robust Independent Elementary Features)算法构建特征描述子。BRIEF算法通过在角点周围选择一组特定的像素点对,并比较它们的灰度值来生成一个二进制编码,用于描述特征点的特征。

  5. 特征点匹配:使用描述子之间的汉明距离Hamming Distance)来度量两个特征点的相似性。通过比较特征点的描述子,找到最佳匹配的特征点。

3.2 代码示例

由于OpenCV库中已经有对应的ORB算法接口,直接调用即可,如下python代码:

import cv2

# 读取输入图像
image = cv2.imread('liuyf.jpg')
# 创建ORB对象
orb = cv2.ORB_create()
# 检测关键点和计算描述子
keypoints, descriptors = orb.detectAndCompute(image, None)
# 可选:绘制关键点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)
# 保存图像
cv2.imwrite('image_with_orb.jpg', image_with_keypoints)
# 显示结果
cv2.imshow('Image with Keypoints', image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中输入左图,输出右图,主要调用了cv2.ORB_create()创建SIFT对象,然后调用orb.detectAndCompute(image, None)检测关键点和计算描述子。

详解SIFT、SURF和ORB特征点检测和描述算法_第5张图片 详解SIFT、SURF和ORB特征点检测和描述算法_第6张图片

4 三者对比

算法 SIFT SURF ORB
原理 SIFT算法通过在不同尺度空间和旋转角度上检测图像中的关键点,并计算每个关键点的局部特征描述子 SURF算法也是基于尺度空间的特征提取方法,使用了积分图像的数据结构来加速计算,并检测图像中的兴趣点,并计算每个兴趣点的局部特征描述子 ORB算法结合了FAST关键点检测器和BRIEF描述子。FAST用于检测关键点,BRIEF用于计算关键点的二进制描述子
特征描述子 SIFT算法生成128维的局部特征描述子 SURF算法生成64维的局部特征描述子 ORB算法生成二进制的局部特征描述子
计算效率 SIFT算法计算效率较低,尤其在计算特征描述子时需要进行大量的高斯模糊和梯度计算操作 SURF算法相对于SIFT算法来说计算效率较高,主要得益于使用积分图像结构来加速计算 ORB算法具有较高的计算效率,主要因为FAST关键点检测器和BRIEF描述子都是基于快速计算的算法
尺度不变性 SIFT算法对于尺度变化具有较好的不变性 SURF算法也具有一定的尺度不变性 ORB算法在尺度变化较大的情况下可能不太稳定
旋转不变性 SIFT算法具有很好的旋转不变性 SURF算法也具有一定的旋转不变性 ORB算法在旋转角度较大的情况下可能不太稳定
鲁棒性 SIFT算法在处理光照变化、噪声等情况下具有较好的鲁棒性 SURF算法对于光照变化和噪声有一定的鲁棒性 ORB算法在光照变化和噪声较小的情况下表现较好


Reference:

  • SIFT 论文:https://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf
  • SURF 论文:https://people.ee.ethz.ch/~surf/eccv06.pdf
  • ORB 论文:https://www.gwylab.com/download/ORB_2012.pdf
  • ORB-SLAM2算法8之特征点提取、生成描述子的ORBextractor



须知少时凌云志,曾许人间第一流。



⭐️

你可能感兴趣的:(计算机视觉,#,OpenCV,计算机视觉,opencv,SIFT,SURF,ORB,特征点检测,描述子)