【OpenCV 例程 300篇】246. 特征检测之ORB算法

『youcans 的 OpenCV 例程300篇 – 总目录』


【youcans 的 OpenCV 例程 300篇】246. 特征检测之ORB算法


特征检测与匹配是计算机视觉的基本任务,包括检测、描述和匹配三个相互关联的步骤。广泛应用于目标检测、图像检索、视频跟踪和三维重建等诸多领域。


6.9.1 ORB 算法简介

ORB(Oriented FAST and rotated BRIEF) 是 OpenCV 实验室开发的一种特征检测与特征描述算法,将 FAST 特征检测与 BRIEF 特征描述结合并进行了改进,具有尺度不变性和旋转不变性,对噪声有较强的抗干扰能力。

ORB算法在图像金字塔中使用FAST算法检测关键点,通过一阶矩计算关键点的方向,使用方向校正的BRIEF生成特征描述符。

FAST(Features From Accelerated Segment Test)是一种关键点检测算法,用于特征提取但不涉及特征描述。FAST 算法通过与圆周像素的比较结果判别特征点,计算速度快、可重复性高,非常适合实时视频的处理。

BRIEF (Binary Robust Independent Elementary Features)是一种二进制特征描述符,直接生成二进制字符串作为关键点的特征描述符,加快了建立特征描述符的速度,降低了特征描述符的内存占用,极大地提高了特征匹配的效率,是一种快速高效的特征描述方法,对光照、模糊和透视变换具有较强的鲁棒性。

基本的FAST和BRIEF算法并不具有尺度不变性和旋转不变性,ORB算法的主要贡献是:
(1)对 FAST 算法提取的特征点,使用一阶矩计算特征点方向,实现旋转不变性;
(2)高效计算带方向的 BRIEF 特征点描述符;
(3)降低 BRIEF 特征描述符点对的相关性,在最近邻匹配中具有更好的性能。

参考文献:Ethan Rublee, Vincent Rabaud, Kurt Konolige, and Gary Bradski. Orb: an efficient alternative to sift or surf. In Computer Vision (ICCV), 2011 IEEE International Conference on, pages 2564–2571. IEEE, 2011.

ORB论文中没有解决尺度不变性,但在OpenCV算法中通过图像金字塔实现了尺度不变性。


ORB的主要步骤如下:

(1)尺度空间关键点检测

通过下采样构造图像金字塔,每层只有一张图像,第s层的尺度为:【OpenCV 例程 300篇】246. 特征检测之ORB算法,第s层的图像尺寸为:【OpenCV 例程 300篇】246. 特征检测之ORB算法
在图像金字塔的每层图像中使用 FAST 检测关键点,然后使用Harris角点响应函数或FAST算法选择响应最强的N个点。通过检测每个尺度的关键点,使算法具有一定的尺度特征。

(2)确定关键点的方向

SIFT的定向算法计算量很大,而SURF的定向算法精度较差。ORB使用质心法对关键点确定唯一的主方向。
在以关键点为中心、尺度半径的邻域中,使用强度质心法(一阶矩)计算关键点的方向:
【OpenCV 例程 300篇】246. 特征检测之ORB算法
通过确定每个关键点的方向, 以实现旋转不变性。

(3)使用rBRIEF(Rotation-Aware BRIEF )生成特征描述符。

BRIEF描述符对于方向变化非常敏感, 存在10度以上旋转时匹配性能很差。
ORB 将角度离散化为2π/30(12度),并构建了BRIEF模式的查找表。rBRIEF根据关键点方向来引导 BRIEF,按关键点的方向将采样窗口旋转角度【OpenCV 例程 300篇】246. 特征检测之ORB算法后再构造特征区域,生成 rBRIEF 特征描述符,因此具有旋转不变性。

(4)rBRIEF 特征描述符的方差

BRIEF描述符的每个关键点对都具有很大的方差(均值接近于0.5),相关性较小,便于增强匹配性能。
但 rBRIEF 会减小特征点对的方差,相关性增大,可识别性降低。
为了恢复 rBRIEF 损失的方差,ORB在所有可能的二进制测试中进行贪婪搜索,以找到具有高方差和相关性弱的二进制点对。

ORB的优点是速度非常快,性能比较好,具有旋转不变性和一定的尺度不变性。由于没有专利限制可以免费使用,ORB 算法应用广泛,经常被用来代替 SIFT、SURF 算法。

计算速度: ORB>>SURF>>SIFT(各差一个量级)
旋转鲁棒性:SURF>ORB~SIFT(~表示差不多)
模糊鲁棒性:SURF>ORB~SIFT
尺度鲁棒性:SURF>SIFT>ORB(ORB的尺度变换性很弱)


6.9.2 OpenCV 中的 ORB 类

OpenCV 提供了丰富的特征检测算法,而且继承了 cv::Feature2D 类,采用了统一的定义和封装。

OpenCV 中提供 cv::ORB 类实现 ORB 算法,ORB 类继承了cv::Feature2D类,通过create静态方法创建。

ORB 类的构造函数为:

static Ptr<ORB> create(int nfeatures=500,float scaleFactor = 1.2f,int nlevels = 8,int edgeThreshold = 31,int firstLevel = 0,int WTA_K = 2,ORB::ScoreType scoreType = ORB::HARRIS_SCORE,int patchSize = 31,int fastThreshold = 20)

ORB 类继承 cv::Feature2D父类,在Python语言中通过接口函数cv.ORB_create或cv.ORB.create实例化ORB类,创建ORB对象。通过成员函数orb.detect检测关键点,函数orb.compute计算关键点描述符,函数orb.detectAndCompute检测关键点并生成描述符。

cv.ORB.create([, nfeatures=500, scaleFactor=1.2f, nlevels=8, edgeThreshold=31, firstLevel=0, WTA_K=2, scoreType=ORB::HARRIS_SCORE, patchSize=31, fastThreshold=20]) → retval
cv.ORB_create([, nfeatures=500, scaleFactor=1.2f, nlevels=8, edgeThreshold=31, firstLevel=0, WTA_K=2, scoreType=ORB::HARRIS_SCORE, patchSize=31, fastThreshold=20]) → retval
orb.detect(image[, mask]) → keypoints
orb.compute(image, keypoints[, descriptors=None]) → keypoints, descriptors
orb.detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]]) → keypoints, descriptors

参数说明:

  • nfeatures:关键点的最大数量,默认值为500。
  • scaleFactor:图像金字塔的缩放比,大于1的浮点数,默认值为1.2。
  • nlevels :图像金字塔的层数,默认值为8。
  • edgeThreshold:边界保留尺寸,不检测靠近边界的像素,默认值为31。
  • firstLevel:原始图像作为金字塔的第几层,默认值为0。
  • WTA_K:构造BRIEF描述符点对的像素点数,可选值2/3/4,默认值为2。
  • scoreType:响应排序方法,默认HARRIS_SCORE,表示按Harris响应函数排序。
  • patchSize:生成定向描述符的特征区域的尺寸,默认值为31。
  • fastThreshold:FAST阈值,默认值为20。
  • image:输入图像,单通道。
  • mask:掩模图像,指定查找关键点的区域,可选项。
  • keypoints:检测到的关键点,元组。
  • descriptors:关键点的描述符,形为(nfeatures,32)的Numpy数组。

注意事项:

  • 通过接口函数cv.ORB.create或cv.ORB_create实例化ORB类,在OpenCV的不同版本中可能只允许其中一种方式。
  • 函数detect、compute、detectAndCompute等是继承Feature2D类的成员函数,在程序中的格式为orb.detect,orb表示ORB类的实例对象。
  • 关键点描述符descriptor的形状为(nfeatures,32),nfeatures是关键点的数量,描述符的字节长度为32,对应于二进制编码长度为256。

例程 14.28:特征检测之 ORB 算法

# 【例程 14.28】特征检测之 ORB 算法
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

if __name__ == '__main__':
    img = cv.imread("../images/Fig1701.png", flags=1)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    print("shape of image: ", gray.shape)

    # Initiate ORB detector
    orb = cv.ORB_create()  # 实例化 ORB 类
    # kp, descriptors = orb.detectAndCompute(gray)  # 检测关键点和生成描述符
    kp = orb.detect(img, None)  # 关键点检测,kp 为元组
    kp, des = orb.compute(img, kp)  # 生成描述符
    print("Num of keypoints: ", len(kp))  # 500
    print("Shape of kp descriptors: ", des.shape)  # (500,32)
    imgS = cv.convertScaleAbs(img, alpha=0.5, beta=128)
    imgKp1 = cv.drawKeypoints(imgS, kp, None)  # 只绘制关键点位置
    imgKp2 = cv.drawKeypoints(imgS, kp, None, flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)  # 绘制关键点大小和方向
    plt.figure(figsize=(9, 3.5))
    plt.subplot(131), plt.title("1. Original")
    plt.axis('off'), plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.subplot(132), plt.title("2. ORB keypoints")
    plt.axis('off'), plt.imshow(cv.cvtColor(imgKp1, cv.COLOR_BGR2RGB))
    plt.subplot(133), plt.title("3. ORB keypoints scaled")
    plt.axis('off'), plt.imshow(cv.cvtColor(imgKp2, cv.COLOR_BGR2RGB))
    plt.tight_layout()
plt.show()



程序说明
程序运行结果如图所示。
⑴ 子图1是原始图像,子图2、子图3将ORB检测的关键点绘制在原始图像上。子图2只绘制了关键点的中心,子图3对每个关键点绘制表示关键点大小和方向的圆圈。
⑵ 例程检测到500个关键点,但子图2中显示的关键点数量似乎并不多。对比子图3可知,在一个关键点及其邻近点,可能在不同尺度被检测为很多个关键点,ORB算法并未对此进行抑制。


参考文献:Ethan Rublee, Vincent Rabaud, Kurt Konolige, and Gary Bradski. Orb: an efficient alternative to sift or surf. In Computer Vision (ICCV), 2011 IEEE International Conference on, pages 2564–2571. IEEE, 2011

【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/128033070)
Copyright 2022 youcans, XUPT
Crated:2022-11-25

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年11月13日
下一篇 2023年11月13日

相关推荐