ORB:Oriented Fast and Rotated Brief。可以用来对图像中的关键点快速创建特征向量,这些特征向量可以用来识别图像中的对象。
其中,Fast 和 Brief 分别是特征检测算法和向量创建算法。ORB 首先会从图像中查找特殊区域,称为关键点。关键点即图像中突出的小区域,比如角点,比如它们具有像素值急剧的从浅色变为深色的特征。然后 ORB 会为每个关键点计算相应的特征向量。ORB 算法创建的特征向量只包含 1 和 0,称为二元特征向量。
1 和 0 的顺序会根据特定关键点和其周围的像素区域而变化。该向量表示关键点周围的强度模式,因此多个特征向量可以用来识别更大的区域,甚至图像中的特定对象。
ORB 的特点是速度非常快,而且在一定程度上不受噪点和图像变换的影响,例如旋转和缩放变换等。
ORB 特征检测的第一步是查找图像中的关键点,这一步骤中使用的是 FAST 算法。
FAST 是 Features from Accelerated Segments Test 的简称,可以快速选择关键点,算法步骤如下:
BRIEF 是 Binary Robust Independent Elementary Features 的简称,它的作用是根据一组关键点创建二进制特征向量,又称为二进制特征描述符,是仅包含 1 和 0 的特征向量。在 BRIEF 中 每个关键点由一个二进制特征向量描述,该向量一般为 128-512 位的字符串,其中仅包含 1 和 0。
BRIEF 算法生成二进制的特征描述符最大优点在于能非常高效地存储在内存中,并且可以快速计算,且使 BRIEF 能够在计算资源非常有限的设备(例如智能手机)上运行。
BRIEF算法生成特征描述符的具体步骤如下:
首先利用高斯核对给定图像进行平滑处理,以防描述符对高频噪点过于敏感。
然后对于给定关键点(例如下图猫爪上的绿点),以该关键点为中心的高斯分布中抽取一个像素,下文将该点称作关键点的一号点(下图中的蓝点),标准差为 σ
以一号点为中心的高斯分布中抽取一个像素,下文将该点称作关键点的二号点(下图中的黄点),标准差为 σ/2【这么取是因为经验表明这种选择提高了特征匹配率】。
为关键点构建二进制特征描述符,方法是比较 2 和 3 得到的一号点和二号点的灰度值。如果一号点比二号点亮,则为描述符中的相应位分配值 1,否则分配值 0。
然后针对同一关键点选择新的一号点和二号点,比较它们的灰度并为特征向量中的下个位分配 1 或 0。(即跳转到2重复循环)
对于设定的生成不同维度的具体程序,BRIEF算法会重复 步骤2 ~ 4 对应的次数,产生指定长度的特征描述符。并对每一特征点重复以上算法。
BRIEF 算法可以生成二进制特征描述符,但并不满足图像的缩放旋转不变性,故不能直接用于要求较高的图像匹配中,为克服这一缺点,将 BRIEF 作下述改进。
为使特征满足缩放不变性, BRIEF 算法构建图像金字塔。
图像金字塔是单个图像的多尺度表示法,由一系列原始图像的不同分辨率版本组成
金字塔的每个级别都由上个级别的图像下采样版本组成。下采样是指图像分辨率被降低,比如图像按照 1/2 比例下采样。因此一开始的 4x4 正方形区域现在变成 2x2 正方形。图像的下采样包含更少的像素,并且以 1/2 的比例降低大小。
上图是一个包含 5 个级别的图形金字塔示例,在每个级别图像都以 1/2 的比例下采样。
ORB 创建好图像金字塔后,会使用 FAST 算法从每个级别不同大小的图像中快速找到关键点。因为金字塔的每个级别由原始图像的更小版本组成,因此原始图像中的任何对象在金字塔的每个级别也会降低大小。
通过确定每个级别的关键点 ORB 能够有效发现不同尺寸的对象的关键点,这样的话 ORB 实现了部分缩放不变性。
疑问:那ORB是把不同level的金字塔分别记录了下来,再拿图片比对各个金字塔得出关键点还是其他?
为满足特征的旋转不变性,ORB 为每个关键点分配一个方向,该方向取决于该关键点周围的灰度是如何变化的。
ORB 首先选择金字塔Level 0 中的图像,计算该图像关键点的方向。
首先计算以该关键点为中心的指定大小方框中的强度形心(灰度强度的形心)。强度形心可以看做给定区域中的平均像素灰度的位置。计算强度形心后,通过画一条从关键点到强度形心的向量,获得该关键点的方向。
如上图所示。这个强度形心为左下方向,因为这个区域的亮度朝着这个方向增强。
为金字塔级别 0 的图像中的每个关键点分配方向后,ORB 现在为所有其他金字塔级别的图像重复相同流程。需要注意的是,在每个图像金字塔级别,关键点周围用于确认方向的区域大小并没有缩减,因此相同区域在每个金字塔级别覆盖的图像区域将更大,导致关键点的大小各不相同。
ORB 现在使用修改后的 BRIEF 版本创建特征向量,这个修改后的 BRIEF 版本称为 rBRIEF,即 Rotation-Aware BRIEF。无论对象的方向如何,它都可以为关键点创建相同的向量,使得 ORB 算法具有旋转不变性,意味着它可以在朝着任何角度旋转的图像中检测到相同的关键点。
和 BRIEF 一样 ,rBRIEF 首先在给定关键点周围的已界定区域中随机选择 256 个像素对,以构建 256 维的位向量。然后根据关键点的方向角度旋转这些随机像素对,使随机点的方向与关键点的一致。最后, rBRIEF 对比随机像素对的亮度并相应地分配 1 和 0 创建对应的特征向量。
疑问:怎么选择随机像素对?真的是旋转具体像素?让后用这个256+关键点的方向角度去判断和其他也经过旋转的图是否一致?
(1)pycharm下python3.7.6 (2)opencv-python 3.4.2.16
(3)opencv-contrib-python 3.4.2.16
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread('C:/Users/dell/Desktop/mayun1.png')
img2 = cv.imread('C:/Users/dell/Desktop/mayun2.png')
img1 = cv.cvtColor(img1, cv.COLOR_RGB2GRAY)
img2 = cv.cvtColor(img2, cv.COLOR_RGB2GRAY)
orb = cv.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck = True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv.drawMatches(img1, kp1, img2, kp2, matches[: 20], None, flags=2)
plt.imshow(img3), plt.show()
cv2.ORB_create(nfeatures = 500, scaleFactor = 1.2, nlevels = 8, edgeThreshold = 31, firstLevel = 0,WTA_K = 2, scoreType = HARRIS_SCORE, patchSize = 31, fastThreshold = 20)
生成关键点的函数
上图即利用ORB算法检测匹配图像特征点,测试程序运行速度很快,且可见效果较好。 但由下图可见,该特征匹配算法在不同光照、环境、状态下的同一目标匹配效果较差,有一定的改进空间。