python 亮度一致_ORB(Oriented FAST and Rotated BRIEF)简介及Python实现

Oriented FAST and Rotated BRIEF (ORB)由Ethan Rublee,Vincent Rabaud,Kurt Konolige和Gary R. Bradski于2011年在OpenCV实验室开发,是SIFT和SURF的有效可行的替代方案。ORB的构思主要是因为SIFT和SURF是专利算法。但是,ORB可以免费使用。论文链接:http://www.willowgarage.com/sites/default/files/orb_final.pdf

704c91ff51853356dd116854fcfc12e9.png

ORB在特征检测任务上的表现与SIFT相同(并且优于SURF),同时速度提高了近两个数量级。ORB建立在众所周知的FAST关键点检测器和BRIEF描述符之上。这两种技术都具有吸引力,因为它们具有良好的性能和低成本。ORB的主要贡献如下:

  • 为FAST添加快速准确的定位组件
  • oriented BRIEF特征的高效计算
  • oriented BRIEF特征的方差和相关性分析
  • 一种用于在旋转不变性下decorrelating BRIEF特征的学习方法,导致最近邻应用中的更好性能

概念

关键点 - 图像中的小区域特别独特。示例:像素值从亮到暗急剧变化的角。

描述符 - 特征描述符是一种提取图像并输出特征描述符/特征向量的算法。特征描述符将信息编码成一系列数字,并充当某种数字“指纹”,可用于区分一个特征与另一个特征。理想情况下,这些信息在图像变换下是不变的,所以即使图像以某种方式变换,我们也可以再次找到特征。

Fast

给定像素数组中的p,快速将p的亮度与围绕p的周围16个像素进行比较。然后将圆中的像素分为三类(比p更亮,比p更暗或与p相似)。如果超过8个像素比p更暗或更亮,则选择它作为关键点。因此,fast发现的关键点为我们提供了确定图像边缘位置的信息。

c79a048e1496d06630c4337e76ba134c.png

FAST特征没有orientation 组件和多尺度特征。所以orb算法使用多尺度图像金字塔。图像金字塔是单个图像的多尺度表示,其由图像序列组成,所有图像都是不同分辨率的图像的版本。金字塔中的每个级别包含图像的下采样版本,而不是前一级别。一旦orb创建了金字塔,它就会使用FAST算法来检测图像中的关键点。通过检测每个级别的关键点,orb可以有效地以不同的比例定位关键点。这样,ORB是部分尺度不变的。

e3e42873455f8e1cb1a8d39373dc466a.png

找到关键点后,orb现在为每个关键点指定一个方向,比如左边或右边,取决于强度变化的程度。为了检测强度变化,orb使用强度质心。强度质心假设角的强度偏离其中心,并且该向量可用于估算方向。

首先,patch的矩(moments)定义为:

bd623006a3f9b27eac4f9da8330671ba.png

ORB描述符 - Patch’s moment’s definition

通过这些矩,我们可以找到质心

eb7b7c86ce90bf20a5439701aabee724.png

ORB描述符 - Center of the mass of the patch

我们可以构造一个向量从角的中心O到质心-OC。那么patch的方向为:

3746ace61703b21c2abf85949458aef2.png

ORB描述符 - Orientation of the patch

这里有一个例子来帮助解释这个方法:

e82541f767e2c9e635688f66054444d1.png

一旦我们计算了patch的方向,我们就可以将其进行旋转,然后计算描述符,从而获得一些旋转不变性。

Brief

Brief采用fast 算法找到的所有关键点并将其转换为二进制特征向量,以便它们一起表示一个对象。二进制特征向量也称为二进制特征描述符,是仅包含1和0的特征向量。简而言之,每个关键点由特征向量描述,该特征向量是128-512位字符串。

2d415597c15003cb18121f949b77898d.png

首先使用高斯核平滑图像,以防止描述符对高频噪声敏感。然后简要选择围绕该关键点的定义邻域中的随机像素pair。像素周围的定义邻域被称为patch,其是一些像素宽度和高度的正方形。随机pair中的第一个像素是以围绕关键点为中心的高斯分布绘制的,该高斯分布具有明显的偏差或sigma离散。随机pair中的第二像素是从以第一像素为中心的高斯分布中绘制的,其标准偏差或西格玛的离散为2。现在,如果第一个像素比第二个像素更亮,则赋值为1,否则0。

1ae53239084dab73f19e75059a8497e4.png

再次,brief 选择一个随机pair 并将值赋给它们。对于128位向量,brief 重复此过程128次以获得关键点。brief 为图像中的每个关键点创建这样的矢量。但是,Brief也不是旋转不变的,所以orb使用rBRIEF(Rotation-aware Brief)。ORB试图添加此功能,同时又不失BRIEF的速度方面的优势。

考虑一个平滑的图像patch,p。一个二进制测试τ被定义为:

4a25e126575d926a5623fb9c1e5d1ba2.png

其中p(x)是点x处的p的强度。该特征被定义为n个二进制测试的向量:

e23ee2f5e9a02896d2373de0f8dbb6dc.png

BRIEF在平面内旋转超过几个度时匹配性能急剧下降。ORB提出了一种根据关键点的方向引导BRIEF的方法。对于位置(xi,yi)的n个二进制测试的任何特征集,我们需要2 xn矩阵:

2fce300a1f4dd0f218955f08d2c20533.png

它使用patch 方向θ和相应的旋转矩阵Rθ,并构造S的steered版本Sθ:

34cf195839eda11b4cffd3f158e62614.png

现在,Brief运算符变为:

7d54afa734d18ee58eeca71526e140e2.png

然后将角度离散化为2π/ 30(12度)的增量,并构建预先计算的Brief模式的查找表。只要关键点方向θ在视图之间是一致的,将使用正确的点集Sθ来计算其描述符。

ORB指定rBRIEF算法如下:

1)针对所有训练patch 运行每个测试。

2)按照它们与平均值0.5的距离对测试进行排序,形成向量T.

3)贪心搜索:

  • 将第一个测试放入结果向量R中,并将其从T中移除。
  • 从T中进行下一个测试,并将其与R中的所有测试进行比较。如果其绝对相关性大于阈值,则将其丢弃; 否则将其添加到R.
  • 重复上一步,直到R中有256个测试。如果少于256个,请提高阈值并再试一次

rBRIEF在方差和相关性方面有显著改善。

Python实现

可以使用OpenCV实现ORB。Python代码如下:

import cv2import matplotlib.pyplot as pltimport numpy as np%matplotlib inline# Load the imageimage1 = cv2.imread('./images/face1.jpeg')# Convert the training image to RGBtraining_image = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)# Convert the training image to gray scaletraining_gray = cv2.cvtColor(training_image, cv2.COLOR_RGB2GRAY)# Create test image by adding Scale Invariance and Rotational Invariancetest_image = cv2.pyrDown(training_image)test_image = cv2.pyrDown(test_image)num_rows, num_cols = test_image.shape[:2]rotation_matrix = cv2.getRotationMatrix2D((num_cols/2, num_rows/2), 30, 1)test_image = cv2.warpAffine(test_image, rotation_matrix, (num_cols, num_rows))test_gray = cv2.cvtColor(test_image, cv2.COLOR_RGB2GRAY)# Display traning image and testing imagefx, plots = plt.subplots(1, 2, figsize=(20,10))plots[0].set_title("Training Image")plots[0].imshow(training_image)plots[1].set_title("Testing Image")plots[1].imshow(test_image)
bff50a4000734885d3ed1c6467e1dac0.png
88f6447ac3397a10536c213122951b72.png
orb = cv2.ORB_create()train_keypoints, train_descriptor = orb.detectAndCompute(training_gray, None)test_keypoints, test_descriptor = orb.detectAndCompute(test_gray, None)keypoints_without_size = np.copy(training_image)keypoints_with_size = np.copy(training_image)cv2.drawKeypoints(training_image, train_keypoints, keypoints_without_size, color = (0, 255, 0))cv2.drawKeypoints(training_image, train_keypoints, keypoints_with_size, flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)# Display image with and without keypoints sizefx, plots = plt.subplots(1, 2, figsize=(20,10))plots[0].set_title("Train keypoints With Size")plots[0].imshow(keypoints_with_size, cmap='gray')plots[1].set_title("Train keypoints Without Size")plots[1].imshow(keypoints_without_size, cmap='gray')# Print the number of keypoints detected in the training imageprint("Number of Keypoints Detected In The Training Image: 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值