BRIEF & ORB
一、BRIEF (Binary Robust Independent Elementary Features) - 二进制鲁棒独立基本特征
本小节我们主要了解BRIEF算法的基本概念
1. 概念
我们知道 SIFT 使用 128 维向量作为描述符。 由于它使用的是浮点数,它一般需要 512 个字节。 同样,SURF 也需要最少 256 个字节(对于 64-dim)。 为数千个特征创建这样的向量会占用大量内存,这对于资源受限的应用程序(尤其是嵌入式系统)来说是不可行的。 内存越大,匹配时间越长。
但实际匹配可能不需要所有这些尺寸。 我们可以使用 PCA、LDA 等多种方法对其进行压缩。甚至其他方法(例如使用 LSH(局部敏感哈希)的哈希)也用于将浮点数中的这些 SIFT 描述符转换为二进制字符串。 这些二进制字符串用于使用汉明距离匹配特征。 这提供了更好的加速,因为找到汉明距离只是应用 XOR 和位数,这在具有 SSE 指令的现代 CPU 中非常快。 但是,我们需要先找到描述符,然后才能应用散列,这并不能解决我们最初的内存问题。
此刻,BRIEF 应运而出。 它提供了一种直接查找二进制字符串而无需查找描述符的快捷方式。 它采用平滑的图像补丁并以独特的方式选择一组位置对(在论文中进行了解释)。 然后对这些位置对进行一些像素强度比较。 例如,让第一个位置对是 p 和 q。 如果 I(p)<I(q),则其结果为 1,否则为 0。这适用于所有 位置对以获得 维位串。
可以是 128、256 或 512。OpenCV 支持所有这些,但默认情况下,它将是 256(OpenCV 以字节表示它。因此值将是 16、32 和 64)。 所以一旦你得到了这个,你就可以使用汉明距离来匹配这些描述符。
重要的一点是,BRIEF 是一种特征描述符,它不提供任何查找特征的方法。 因此,您将不得不使用任何其他特征检测器,如 SIFT、SURF 等。本文建议使用 CenSurE,它是一种快速检测器,BRIEF 对 CenSurE 点的效果甚至比对 SURF 点的效果要好一些。
简而言之,BRIEF是一种更快计算和匹配特征描述符的方法。 除非存在较大的平面内旋转,否则它还提供高识别率。
2. OpenCV中的STAR(CenSurE)
STAR 是源自 CenSurE 的特征检测器。 然而,与使用正方形、六边形和八边形等多边形来接近圆形的 CenSurE 不同,Star 模拟具有 2 个重叠正方形的圆形:1 个直立的和 1 个 45 度旋转的。 这些多边形是双层的。 它们可以被视为具有厚边界的多边形。 边界和封闭区域具有相反标志的权重。 这比其他尺度空间检测器具有更好的计算特性,并且能够实时实现。 与 SIFT 和 SURF 相比,它们在子采样像素处发现极值,这会损害更大尺度的精度,而 CenSurE 在金字塔的所有尺度上使用全空间分辨率创建特征向量。
3. OpenCV中的BRIEF
下面的代码显示了在 CenSurE 检测器的帮助下对简要描述符的计算。 请注意,您需要 opencv contrib github.com/opencv/open…) 才能使用它。
import cv2 as cv
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
def cv_show(name, img):
cv.imshow(name, img)
cv.waitKey(0)
cv.destroyAllWindows()
def compare(imgs):
# for i in range(len(imgs)):
# imgs[i][:,-3:-1,:] = [255,255,255]
res = np.hstack(imgs)
cv_show('Compare', res)
img = cv.imread('lena.png',0)
# 初始化FAST检测器
star = cv.xfeatures2d.StarDetector_create()
# 初始化BRIEF提取器
brief = cv.xfeatures2d.BriefDescriptorExtractor_create()
# 使用STAR检测关键点
kp = star.detect(img,None)
# 使用BRIEF计算关键点描述
kp, des = brief.compute(img, kp)
print( brief.descriptorSize() )
print( des.shape )
32
(138, 32)
函数 brief.getDescriptorSize() 给出了以字节为单位的 大小。 默认为 32。下一个是匹配,这将在另一章中完成。
# 查看OpenCV版本号便于安装适配的OpenCV-contrib-python
cv.__version__
'4.5.5'
二、ORB(面向 FAST 和 Rotated Brief)
本小节我们介绍一下ORB的基本概念
1. 概念
作为一个OpenCV爱好者,ORB最重要的是它来自“OpenCV Labs”。 该算法由 Ethan Rublee、Vincent Rabaud、Kurt Konolige 和 Gary R. Bradski 在他们的论文 ORB: An Effective Alternative to SIFT or SURF 在 2011 年提出。正如标题所说,它是计算中 SIFT 和 SURF 的一个很好的替代方案 成本,匹配性能,主要是专利。 是的,SIFT 和 SURF 已获得专利,您应该为其使用付费。 但是ORB不是!!!
ORB 基本上是 FAST 关键点检测器和简要描述符的融合,并进行了许多修改以提高性能。 首先它使用 FAST 找到关键点,然后应用 Harris 角点测量来找到其中的前 N 个点。 它还使用金字塔来产生多尺度特征。 但一个问题是,FAST 不计算方向。 那么旋转不变性呢? 作者提出了以下修改。
它计算以中心角为中心的贴片的强度加权质心。 从这个角点到质心的向量的方向给出了方向。 为了提高旋转不变性,用 x 和 y 计算矩,它们应该在半径为 r 的圆形区域中,其中 r 是补丁的大小。
现在对于描述符,ORB 使用简要描述符。 但是我们已经看到,BRIEF 在旋转方面表现不佳。 所以 ORB 所做的就是根据关键点的方向“引导”BRIEF。 对于位置的任何 n 个二进制测试的特征集,定义一个 2×n 矩阵 S,其中包含这些像素的坐标。 然后使用补丁的方向θ,找到它的旋转矩阵并旋转S以获得转向(旋转)版本。
ORB 将角度离散化为 2π/30(12 度)的增量,并构造一个预先计算的 BRIEF 模式的查找表。 只要关键点方向 θ 在各个视图中是一致的,那么正确的点集 将用于计算其描述符。
Brief 有一个重要的特性,即每个比特特征的方差都很大,均值接近 0.5。 但是一旦它沿着关键点方向定向,它就会失去这个属性并且变得更加分散。 高方差使特征更具辨别力,因为它对输入的响应不同。 另一个理想的属性是使测试不相关,因为这样每个测试都会对结果有所贡献。 为了解决所有这些问题,ORB 在所有可能的二进制测试中运行贪婪搜索,以找到具有高方差和均值接近 0.5 以及不相关的测试。 结果称为 rBRIEF。
对于描述符匹配,使用了对传统 LSH 进行改进的多探针 LSH。 论文说 ORB 比 SURF 和 SIFT 快得多,并且 ORB 描述符比 SURF 工作得更好。 ORB是全景拼接等低功耗设备的不错选择。
2. OpenCV中的ORB
像往常一样,我们必须使用函数 cv.ORB() 或使用 feature2d 通用接口创建一个 ORB 对象。 它有许多可选参数。 最有用的是 nFeatures 表示要保留的最大特征数(默认为 500), scoreType 表示是 Harris 分数还是 FAST 分数来对特征进行排名(默认情况下为Harris 分数)等。另一个参数 WTA_K 决定点数 产生定向BRIEF描述符的每个元素。 默认为两个,即一次选择两个点。 在这种情况下,为了匹配,使用 NORM_HAMMING 距离。 如果 WTA_K 为 3 或 4,需要 3 或 4 个点来生成简要描述符,则匹配距离由 NORM_HAMMING2 定义。
# 读入灰度图
img = cv.imread('lena.png',0)
# Initiate ORB detector
orb = cv.ORB_create()
# 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 = cv.drawKeypoints(img, kp, None, color=(0,255,0), flags=0)
compare([cv.merge([img,img,img]),img2])