
一、说明
特征点算法是图像处理中主要算法之一,它是图像物体匹配的关键步骤,因此,是个极其重要的题目,至今依旧研究不断,本篇讲述历年来学者在领域研究的突出贡献,即六种不同的特征点提取办法,供学习者参考学习。
内容
1 FAST(加速分段测试的特点)
2.BRIEF (二元鲁棒独立基本特征)
3. SIFT(尺度不变特征变换)
4. SURF(加速鲁棒功能)
5. ORB(快速定向和旋转BRIEF)
二、FAST(加速分段测试的特点)
FAST 是一种用于识别图像中兴趣点的算法。兴趣点具有较高的局部信息内容,并且它们应该在不同图像之间理想地可重复。FAST 算法工作背后的原因是开发一种兴趣点检测器,用于实时帧速率应用(例如移动机器人上的 SLAM),这些应用的计算资源有限。
算法如下:
- 在强度 IP 的图像中选择像素“p”。这是要被识别为兴趣点或不是兴趣点的像素。
- 设置阈值强度值 T。
- 考虑围绕像素 p 的 16 个像素的圆。
- 如果需要将像素检测为兴趣点,则 16 个像素中的“N”个连续像素需要高于或低于 IP 值 T。
- 为了使算法更快,首先将圆的像素1、5、9和13的强度与IP进行比较。从上图可以看出,这四个像素中至少有三个满足阈值标准,兴趣点才会存在。
- 如果四个像素值中的至少三个——I1、I5、I9、I13不高于或低于IP+T,则P不是兴趣点(角点)。在这种情况下,我们拒绝将像素 p 作为可能的兴趣点。否则,如果至少有 3 个像素高于或低于 Ip + T,则检查所有 16 个像素。
- 对图像中的所有像素重复该过程。
机器学习方法
- 选择一组图像进行训练,运行FAST算法检测兴趣点
- 对于每个像素“p”,将其周围的 16 个像素存储为向量,并对所有像素重复此操作
- 现在这是向量 P,其中包含用于训练的所有数据。
- 向量中的每个值可以采用三种状态。比 p 深、比 p 浅或与 p 相似。
- 根据状态,整个向量 P 将被细分为三个子集:Pd、Ps、Pb。
- 定义一个变量 Kp,如果 p 是兴趣点,则为 true;如果 p 不是兴趣点,则为 false。
- 使用 ID3 算法(决策树分类器)使用变量 Kp 查询每个子集,以获得有关真实类别的知识。
- ID3算法的工作原理是熵最小化。以这样的方式查询 16 个像素,即以最少的查询次数找到真正的类别(是否感兴趣点)。或者换句话说,选择具有最多像素信息的像素x
- 将此熵最小化递归地应用于所有三个子集。
- 当子集的熵为零时终止该过程。
- 决策树学习到的这种查询顺序也可以用于其他图像中的更快检测。
用于移除相邻角点的非极大值抑制
检测彼此相邻的多个兴趣点是该算法初始版本的其他问题之一。这可以通过在检测兴趣点后应用非极大值抑制来解决。我们为每个检测到的点计算一个得分函数 V。得分函数定义为:“连续弧内的像素与中心像素之间的绝对差之和”。我们比较两个相邻的值并丢弃较低的值。
三、Brief(二元鲁棒独立基本特征)
Brief提供了一种直接查找二进制字符串而不需要查找描述符的快捷方式。它采用平滑的图像块并以独特的方式选择一组 n𝒹(x,y) 位置对(在论文中进行了解释)。然后对这些位置对进行一些像素强度比较。例如,令第一位置对为p和q。如果 I(p) <I(q) ,则其结果为 1,否则为 0。这适用于所有 n𝒹 位置对,以获得 n𝒹 维位串。这个n𝒹可以是128、256或512。所以一旦我们得到这个,我们就可以使用汉明距离来匹配这些描述符。
OpenCV 简介
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('simple.jpg',0)
# Initiate STAR detector
star = cv2.FeatureDetector_create("STAR")
# Initiate BRIEF extractor
brief = cv2.DescriptorExtractor_create("BRIEF")
# find the keypoints with STAR
kp = star.detect(img,None)
# compute the descriptors with BRIEF
kp, des = brief.compute(img, kp)
print brief.getInt('bytes')
print des.shape
四、SIFT(尺度不变特征变换)
它是一种用于检测图像中显着、稳定的特征点的技术。对于每个这样的点,它提供一组对旋转和缩放不变的特征。
SIFT算法有四个步骤:
•确定显着特征点(也称为关键点)的大致位置和规模
•完善其位置和规模
•确定每个关键点的方向。
•确定每个关键点的描述符。
4.1 大概位置
SIFT 算法使用高斯差分,它是 LoG 的近似值。这个过程是针对高斯金字塔中图像的不同八度音程完成的。一旦找到这个 DoG,就会在图像上搜索尺度和空间上的局部极值。它基本上意味着关键点在该比例中得到了最好的体现。
关键点定位
一旦找到潜在的关键点位置,就必须对其进行细化以获得更准确的结果。他们使用尺度空间的泰勒级数展开来获得更准确的极值位置,如果该极值处的强度小于阈值(论文中为 0.03),则将其拒绝。这个阈值在OpenCV中称为contrastThreshold。
DoG对边缘的响应较高,因此也需要去除边缘。为此,使用了类似于 Harris 角点检测器的概念。他们使用 2x2 Hessian 矩阵 (H) 来计算主曲率。所以这里我们使用一个简单的函数:如果这个比率大于阈值,则该关键点被丢弃。因此,它消除了任何低对比度关键点和边缘关键点,剩下的是强烈兴趣点。
指定方向
现在,为每个关键点分配一个方向,以实现图像旋转的不变性。根据比例在关键点位置周围获取邻域,并计算该区域中的梯度大小和方向。创建包含 36 个箱、覆盖 360 度的方向直方图。它通过梯度幅值和高斯加权圆形窗口进行加权,其中 σ 等于关键点尺度的 1.5 倍。取直方图中的最高峰值,并且任何高于 80% 的峰值也被视为计算方向。它创建具有相同位置和比例但方向不同的关键点。它有助于匹配的稳定性。
每个关键点的描述符
现在关键点描述符已创建。选取关键点周围的 16x16 邻域。它被分为 16 个 4x4 大小的子块。对于每个子块,都会创建一个 8 bin 方向直方图。它被表示为向量以形成关键点描述符。除此之外,还采取了多种措施来实现对光照变化、旋转等的鲁棒性。
4.2 应用:匹配SIFT描述符
通过识别最近的邻居来匹配两个图像之间的关键点。但在某些情况下,第二个最接近的匹配可能非常接近第一个。这可能是由于噪音或其他原因造成的。在这种情况下,将采用最近距离与次近距离的比率。如果大于0.8,则被拒绝。它消除了大约 90% 的错误匹配,而仅丢弃 5% 的正确匹配。
SIFT 用于创建全景视图
OpenCV 中的 SIFT
import cv2
import numpy as np
img = cv2.imread('home.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT()
kp = sift.detect(gray,None)
img=cv2.drawKeypoints(gray,kp)
cv2.imwrite('sift_keypoints.jpg',img)
五、SURF(加速鲁棒功能)
获取SURF描述符有两个阶段,首先检测SURF点,然后提取SURF点处的描述符。SURF点的检测利用尺度空间理论。为了检测 SURF 点,使用 Fast-Hessian 矩阵。Hessian矩阵的行列式用于决定一个点是否可以被选为兴趣点。在图像 I 中,点 X 处的 Hessian 矩阵定义为:
在与图像进行卷积之前需要对高斯二阶导数进行离散化。Dxx 、 Dyy 和 Dxy 表示盒式滤波器与图像的卷积。这些近似二阶高斯导数计算可以通过使用积分图像来快速完成。
通过改变盒式滤波器的大小来分析图像的尺度空间。一般来说,盒式滤波器以默认大小 9x9 开始,对应于 σ= 1.2 的高斯导数。滤波器尺寸随后放大至 15x15、21x21、27x27 等尺寸。在每个尺寸下计算 Hessian 矩阵的近似行列式,并应用 333 个邻域中的非极大值抑制来查找最大值。SURF点的位置和尺度s是通过最大值获得的。
使用哈尔小波响应指定获得的 SURF 点的方向。在SURF点附近,即半径6s内,在x和y方向上计算Haar小波响应。使用这些响应,可以确定主导方向。在主导方向上,构造一个以 SURF 点为中心、大小为 20s 的正方形。这分为 44 个子区域。在每个子区域中,在 55 个规则放置的样本点处计算水平和垂直 Haar 小波响应 dx 和 dy。这些响应在特定区间内求和,得到 Σdx 、 Σdy 。此外,这些响应的绝对值在特定区间内求和,得出 Σ|dx| ,Σ|dy|。使用这些值,为每个子区域构建 4 维特征向量 V = (Σdx , Σdy, Σ|dx| , Σ|dy|)。因此,每个提取的 SURF 点都与一个 4x(4x4) 描述符相关联,这是一个 64 维描述符。该64维描述符用于执行匹配操作。
六、 ORB(快速定向和旋转BRIEF)
ORB 基本上是 FAST 关键点检测器和 Brief 描述符的融合,并进行了许多修改以增强性能。首先它使用 FAST 来查找关键点,然后应用 Harris 角点度量来查找其中的前 N 个点。它还使用金字塔来生成多尺度特征。
ORB算法:
它计算角位于中心的补丁的强度加权质心。从该角点到质心的矢量方向给出了方向。为了提高旋转不变性,用 x 和 y 计算矩,它们应该位于半径为 r 的圆形区域中,其中 r 是面片的大小。现在对于描述符,ORB 使用 Brief 描述符。BRIEF 是旋转不变的,因此 ORB 根据关键点的方向来控制 Brief。对于位置 xᵢ,yᵢ 处的 n 个二进制测试的任何特征集,定义一个 2 xn 矩阵 S,其中包含这些像素的坐标。然后使用面片的方向 θ ,找到其旋转矩阵并旋转 S 以获得转向(旋转)版本 Sθ 。
由于旋转不变,BRIEF 变得更加分布式。ORB 在所有可能的二元测试中运行贪心搜索,以找到方差高且均值接近 0.5 并且不相关的测试。结果称为rBRIEF。对于描述符匹配,使用了对传统 LSH 进行改进的多探针 LSH。
OpenCV 中的 ORB:
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('simple.jpg',0)
# Initiate STAR detector
orb = cv2.ORB()
# find the keypoints with ORB
kp = orb.detect(img,None)
# compute the descriptors with ORB
kp, des = orb.compute(img, kp)
# draw only keypoints location,not size and orientation
img2 = cv2.drawKeypoints(img,kp,color=(0,255,0), flags=0)
plt.imshow(img2),plt.show()
使用 ORB 进行图像匹配
