OpenCV开发教程之SURF和ORB特征检测

8人浏览 / 0人评论 / 添加收藏

在 OpenCV 中,SURFORB 是两种非常经典的特征检测与描述算法。它们的核心目标都是找到图像中稳定、独特的“关键点”,并用数学向量(描述子)来描述这些点周围的特征,以便在不同图像间进行匹配。不过,两者的设计哲学、速度和适用场景截然不同。

SURF(Speeded-Up Robust Features)

SURF 可以看作是 SIFT 的“加速版”,追求在保持高精度的同时提升速度。

原理与特点

检测器:基于 Hessian 矩阵 来检测“斑点”状结构,并使用盒状滤波器(box filter)近似高斯二阶导数,借助积分图像实现快速计算。

描述子:通过计算关键点邻域内的 Haar 小波响应 来确定主方向,再生成一个 64 维或 128 维的浮点型描述子

不变性:具有尺度不变性旋转不变性

专利与速度:SURF 算法受专利保护,因此被放置在 opencv-contrib-python 扩展包中。其速度比 SIFT 快,但仍慢于 ORB 等二值描述子算法。

ORB(Oriented FAST and Rotated BRIEF)

ORB 是为实时应用而生的免费算法,完美平衡了速度与效果,是目前最流行的方案之一。

原理与特点

检测器:使用 FAST 算法提取角点,通过构建图像金字塔实现尺度不变性,并利用灰度质心法为每个角点增加方向,成为 oFAST

描述子:采用 rBRIEF(旋转感知的 BRIEF),是一种二进制描述子,仅由 0 和 1 组成的向量(通常 256 位)。

不变性:具有尺度不变性旋转不变性

专利与速度完全免费,无专利限制,是 OpenCV 主库的一部分。速度极快,尤其适合移动端和嵌入式设备。

# ORB特征检测
# ORB (Oriented FAST and Rotated BRIEF)是一种快速特征点提取和描述的算法。这个算法是由Ethan Rublee,
#   Vincent Rabaud, Kurt Konoligel及Gary R.Bradski在2011年-篇名为 "ORB: An Efficient Alternative 
#   toSIFTor SURF" (http://www.willowgarage.com/sites/default/files/orb_final.pdf )文章中提出.
#   ORB算法为两部分,分别是特征点提取和特征点描述。特征提取是由FAST(Features from Accelerated SegmentTest) 
#   算法发展来的,特征点描述是根据BRIEF (Binary Robust IndependentElementary Features)特征描述算法改进的。
#   ORB特征是将FAST特征点的检测方法与BRIEF特征描述子结合起来,并在它们原来的基础上做了改进与优化。ORB算法最大的特点
#   就是计算速度快。这首先得益于使用FAST检测特征点,FAST的检测速度正如它的名字一样是出了名的快。再次是使用BRIEF算法
#   计算描述子,该描述子特有的2进制串的表现形式不仅节约了存储空间,而且大大缩短了匹配的时间。
# ORB最大的优势就是可以做到实时检测
# ORB的劣势是检测准确性略有下降.
# ORB还有一个优势是ORB是开源的算法,没有版权问题,可以自由使用.SIFT和SURF都被申请了专利.

# SURF特征检测
# Speeded Up Robust Features (SURF,加速稳健特征),是一种稳健的局部特征点检测和描述算法。
#   最初由Herbert Bay发表在2006年的欧洲it算机视觉国际会议 (Europen Conference on Computer Vision,ECCV)上.
#   并在2008年正式发表在Computer Vision and Image Understanding期刊上.
# Surf是对David Lowe在1999年提出的Sif算法的改进,提升了算法的执行效率,为算法在实时计算机视觉系统中应用提供了可能。
# SIFT最大的问题就是速度慢,因此才有了SURF.
# 如果想对一系列的图片进行快速的特征检测,使用SIFT会非常慢.
# 注意:SURF在较新版本的OpenCV中已经申请专利,需要降OpenCV版本才能使用.降到3.4.1.15就可以用了.

# 三种算法对比
# SIFT最慢,准确率最高
# SURF速度比SIFT快些,准确率差些
# ORB速度最快,可以实时检测,准确率最差

实例代码如下:


import cv2
print(cv2.getVersionString())
import numpy as np
from opencv_jupyter_ui import cv2_imshow


img = cv2.imread('./images/hand.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#创建SURF对象
# surf = cv2.xfeatures2d.SURF_create()
# surf = cv2.SURF_create()
# 使用 ORB (速度快,开源免费)
orb = cv2.ORB_create()
# sift = cv2.SIFT_create()

#进行检测
# kp = surf.detect(gray)
# kp = orb.detect(gray)
# print(kp)

#检测关键点,并计算描述子
# kp, des = surf.compute(gray, kp)
#或者一步到位,把关键点和描述子一起检测出来
kp, des = orb.detectAndCompute(gray, None)
print(type(des))
print(des.shape)

# 绘制关键点
cv2.drawKeypoints(gray, kp, img)

# cv2.imshow('img', img)
cv2_imshow('img', img)

展示效果图如下:

 

全部评论