『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层的尺度为:
    
     
      
       
        
         σ
        
        
         s
        
       
       
        =
       
       
        
         σ
        
        
         0
        
        
         s
        
       
      
      
       \sigma_s=\sigma_0^s
      
     
    σs=σ0s,第s层的图像尺寸为:
    
     
      
       
        S
       
       
        i
       
       
        z
       
       
        e
       
       
        =
       
       
        (
       
       
        H
       
       
        /
       
       
        
         σ
        
        
         s
        
       
       
        ,
       
       
        W
       
       
        /
       
       
        
         σ
        
        
         s
        
       
       
        )
       
      
      
       Size=(H/\sigma_s, W/\sigma_s)
      
     
    Size=(H/σs,W/σs)。
 在图像金字塔的每层图像中使用 FAST 检测关键点,然后使用Harris角点响应函数或FAST算法选择响应最强的N个点。通过检测每个尺度的关键点,使算法具有一定的尺度特征。
(2)确定关键点的方向
SIFT的定向算法计算量很大,而SURF的定向算法精度较差。ORB使用质心法对关键点确定唯一的主方向。
 在以关键点为中心、尺度半径的邻域中,使用强度质心法(一阶矩)计算关键点的方向:
 
     
      
       
        
         (
        
        
         
          C
         
         
          x
         
        
        
         ,
        
        
         
          C
         
         
          y
         
        
        
         )
        
        
         =
        
        
         (
        
        
         
          m
         
         
          10
         
        
        
         /
        
        
         
          m
         
         
          00
         
        
        
         ,
        
        
         
          m
         
         
          01
         
        
        
         /
        
        
         
          m
         
         
          00
         
        
        
         )
        
        
        
         θ
        
        
         =
        
        
         a
        
        
         r
        
        
         c
        
        
         t
        
        
         a
        
        
         n
        
        
         (
        
        
         
          m
         
         
          01
         
        
        
         ,
        
        
         
          m
         
         
          10
         
        
        
         )
        
       
       
         (C_x, C_y) = (m_{10}/m_{00}, m_{01}/m_{00}) \\ \theta = arctan(m_{01}, m_{10}) 
       
      
     (Cx,Cy)=(m10/m00,m01/m00)θ=arctan(m01,m10)
 通过确定每个关键点的方向, 以实现旋转不变性。
(3)使用rBRIEF(Rotation-Aware BRIEF )生成特征描述符。
BRIEF描述符对于方向变化非常敏感, 存在10度以上旋转时匹配性能很差。
 ORB 将角度离散化为2π/30(12度),并构建了BRIEF模式的查找表。rBRIEF根据关键点方向来引导 BRIEF,按关键点的方向将采样窗口旋转角度
    
     
      
       
        θ
       
      
      
       \theta
      
     
    θ后再构造特征区域,生成 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



















