OpenCV Python ORB (Oriented FAST and Rotated BRIEF)
【目标】
- 理解 ORB 的基础理论
【理论】
ORB 来自于 OpenCV 实验室;在ICCV2011的论文 “ORB: An efficient alternative to SIFT or SURF” 提出,是 SIFT 和 SURF 的替代,没有专利问题;
ORB基本上是FAST关键点检测器和 BRIEF
描述符的融合,并进行了许多改进以增强性能。该算法首先利用FAST算法找到关键点,然后利用Harris角点测度找到关键点中的前N个点。它还使用金字塔来生成多尺度的特征。但有一个问题是,FAST并不计算方向。那么旋转不变性呢?作者提出了以下修改。
计算局部角点为中心的Patch的亮度加权重心,方向就是角点到重心的连线。为了提高旋转不变性,用 x x x和 y y y计算力矩,它们应位于半径为 r r r的圆形区域内,其中 r r r为patch的大小。
对于描述符,ORB
使用 BRIEF
描述符。但是我们已经看到 BRIEF
在旋转时表现不佳。所以 ORB
所做的就是根据关键点的方向来“控制” BRIEF
。对于位置
(
x
i
,
y
i
)
(x_i, y_i)
(xi,yi)的n个二进制测试的任何特征集,定义一个
2
×
n
2×n
2×n矩阵
S
S
S,其中包含这些像素的坐标。然后使用patch的方向
θ
θ
θ,找到它的旋转矩阵,并旋转
S
S
S以获得转向(旋转)版本
S
θ
Sθ
Sθ。
ORB将角度离散为 12 份,每份角度为 30度,并构造一个预先计算的BRIEF模式查找表。只要关键点方向 θ θ θ在视图中是一致的,正确的点 S θ Sθ Sθ将被用来计算它的描述符。
BRIEF有一个重要的特性,即每个位特征的方差较大,均值接近0.5。但一旦它沿着关键点方向定向,它就失去了这种性质,变得更加分散。高方差使特征更具鉴别性,因为它对输入的反应不同。另一个理想的特性是让测试不相关,因为这样每个测试都会对结果有贡献。为了解决所有这些问题,ORB在所有可能的二进制测试中运行贪婪搜索,以找到方差高且均值接近0.5且不相关的二进制测试。结果称为 rBRIEF
。
对于描述符匹配,采用了改进传统LSH的多探针LSH。文章说ORB比SURF和SIFT快得多,ORB描述符比SURF好得多。ORB是低功耗全景拼接等设备的良好选择。
【代码】
import numpy as np
import cv2
from matplotlib import pyplot as plt
#
img = cv2.imread("assets/blox.jpg", 0)
# 初始化ORB检测器
orb = cv2.ORB_create()
# 检测 特征点
kp = orb.detect(img, None)
print(len(kp))
# 特征描述
kp, des = orb.compute(img, kp)
# 绘制特征点
img2 = cv2.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0)
cv2.imshow("img", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
【接口】
cv2.ORB_create( [, nfeatures[, scaleFactor[, nlevels[, edgeThreshold[, firstLevel[, WTA_K[, scoreType[, patchSize[, fastThreshold]]]]]]]]] ) -> retval
ORB 创建
- nfeatures: 保留的最多的特征数
- scaleFactor: 金字塔抽取比,默认为 2,经典的金字塔
- nlevels: 金字塔层级数,最小层级大小为 input_image_linear_size/pow(scaleFactor, nlevels - firstLevel)
- edgeThreshold: 特征取否的阈值,
- firstLevel: 送到金字塔的第一层,前一层就上采样
- WTA_K: 产生BRIEF描述符每个元素点的数目,默认值为2;也可能是3和4,3则意味着取3个随机点(这些点是随机的,它们是由预定义的种子生成的,因此BRIEF描述符的每个元素都是从像素矩形中确定性计算出来的。)找到亮度最大的点和获胜者的输出索引(0,1或2),这样输出占用2位,因此它将需要一个特殊的汉明距离变体,记为 NORM_HAMMING2(每Bin 2位) ,当WTA_K = 4时,我们取4个随机点来计算每个bin。
- scoreType: HARRIS_SCORE 默认,可以用于对特征进行排序;FAST_SCORE 可以计算更快一点,但是没那么稳定。
- patchSize: 方向 BRIEF 描述符的 Patch 尺寸。
- fastThreshold: fast阈值;
cv2.ORB.getDefaultName( ) -> retval
cv2.ORB.getEdgeThreshold( ) -> retval
cv2.ORB.getFastThreshold( ) -> retval
cv2.ORB.getFirstLevel( ) -> retval
cv2.ORB.getMaxFeatures( ) -> retval
cv2.ORB.getNLevels( ) -> retval
cv2.ORB.getPatchSize( ) -> retval
cv2.ORB.getScaleFactor( ) -> retval
cv2.ORB.getScoreType( ) -> retval
cv2.ORB.getWTA_K( ) -> retval
cv2.ORB.setEdgeThreshold( edgeThreshold ) -> None
cv2.ORB.setFastThreshold( fastThreshold ) -> None
cv2.ORB.setFirstLevel( firstLevel ) -> None
cv2.ORB.setMaxFeatures( maxFeatures ) -> None
cv2.ORB.setNLevels( nlevels ) -> None
cv2.ORB.setPatchSize( patchSize ) -> None
cv2.ORB.setScaleFactor( scaleFactor ) -> None
cv2.ORB.setScoreType( scoreType ) -> None
cv2.ORB.setWTA_K( wta_k ) -> None
【参考】
- OpenCV: ORB (Oriented FAST and Rotated BRIEF)
- Ethan Rublee, Vincent Rabaud, Kurt Konolige, Gary R. Bradski: ORB: An efficient alternative to SIFT or SURF. ICCV 2011: 2564-2571.
- OpenCV: cv::ORB Class Reference