ORB 是计算机视觉中 核心的局部特征提取与匹配算法
ORB = Oriented FAST and Rotated BRIEF ,是一种高效、二进制(binary)描述子的局部特征方法。它结合了 FAST(关键点检测)与 BRIEF(描述子),并通过引入关键点方向与图像金字塔来获得对旋转和一定尺度变化的不变性。适合实时或嵌入式场景(速度快、内存小)。
关键点(Keypoints)
- 图像中具有"显著性"的位置,比如角点、边缘交点、纹理丰富区域。
- 这些点在视角变化、轻微旋转或缩放下仍能被稳定检测到。
描述子(Descriptor)
- 对每个关键点周围的局部区域(比如 32×32 像素)进行编码,生成一个数值向量(如 256 维),用来描述该区域的纹理/结构。
- 这个向量要满足:同一物体的关键点,即使在不同图像中,其描述子也应相似。
ORB 的两大组件:
-
FAST:用于检测关键点(速度很快,但本身无方向/尺度信息)。
-
BRIEF:一种二值描述子,通过对一对像素做强度比较得到 0/1 位串(极快且紧凑,但对旋转不变性差)。
ORB 对 FAST 和 BRIEF 做了两个关键改进:
-
用"方向"使 BRIEF 旋转不变(Oriented BRIEF)。
-
在图像金字塔上检测关键点以获得尺度不变性的部分支持。
一、先明确:ORB 的全称及整体定位
ORB = Oriented + FAST + and + Rotated + BRIEF
中文直译:带方向的 FAST 角点检测 + 旋转不变的 BRIEF 特征描述子
- 核心用途:在图像中找到「有代表性的局部特征点」(比如角点、边缘交点),并给每个特征点生成「独一无二的描述子」,后续可用于 图像匹配、目标跟踪、SLAM(即时定位与地图构建)、图像拼接 等场景。
- 优势:免费(开源)、速度快(比 SIFT 快两个数量级)、对光照变化、旋转、尺度缩放都有鲁棒性(即环境变了也能准确识别特征)。
| 单词 | 英文全称 | 中文含义 | 在 ORB 中的核心作用 |
|---|---|---|---|
| Oriented | Oriented | 带方向的 | 给 FAST 检测到的特征点「赋予方向」,解决 FAST 原本没有旋转不变性的问题(比如图片旋转后,特征点还能被识别)。 |
| FAST | Features from Accelerated Segment Test | 加速分段测试特征点 | 负责「快速检测图像中的角点」(特征点的核心类型),是 ORB 的 "特征点检测器"。 |
| Rotated | Rotated | 旋转后的 | 给 BRIEF 生成的描述子「加入旋转信息」,解决 BRIEF 原本没有旋转不变性的问题。 |
| BRIEF | Binary Robust Independent Elementary Features | 二进制鲁棒独立基本特征 | 负责给 FAST 检测到的角点「生成二进制描述子」,是 ORB 的 "特征描述子生成器"。 |
二、重点详解:FAST 和 BRIEF (ORB 的两大核心模块)
ORB 本质是「改进版的 FAST + 改进版的 BRIEF」
1. FAST:快速角点检测器("找特征点" 的模块)
(1)通俗理解:什么是 FAST?
FAST 的核心任务是 在图像中快速找到 "角点"------ 角点就是图像中「灰度变化剧烈、周围像素明暗对比明显」的点。
- Features:特征 → 这里特指 "角点特征"(图像中最稳定、最易识别的局部特征)。
- from:来自 → 说明特征是从 "加速分段测试" 中提取的。
- Accelerated:加速 → FAST 算法的核心优势!比传统角点检测(如 Harris 角点)快 10-100 倍,适合实时场景(比如视频跟踪)。
- Segment Test:分段测试 → 这是 FAST 检测角点的核心逻辑。
(2)FAST 检测角点的通俗原理
传统角点检测要算复杂的矩阵(比如 Harris 角点的协方差矩阵),FAST 简化成 "简单的灰度对比",步骤如下:
- 遍历图像中每个像素点(比如点 P);
- 以 P 为中心,画一个半径为 3 的圆,圈出周围 16 个像素(形成一个 "环形");
- 分段测试:如果这 16 个像素中,连续有 12 个像素的灰度值,要么都比 P 亮很多,要么都比 P 暗很多(超过设定阈值),就判定 P 是角点。→ 因为角点周围的灰度变化一定是 "突变" 的,而平坦区域(比如白墙)或边缘(比如直线)不会满足这个条件。
(3)FAST 的缺点(为 ORB 的 "Oriented" 改进做铺垫)
- 没有「方向不变性」:比如一张图片旋转 90 度后,原本的角点方向变了,FAST 可能认不出来;
- 没有「尺度不变性」:图片放大 / 缩小后,原本的角点可能被误判(比如小图的角点放大后变成了 "平坦区域")。
2. BRIEF:二进制特征描述子("给特征点编身份证" 的模块)
(1)通俗理解:什么是 BRIEF?
BRIEF 的核心任务是 给 FAST 检测到的每个角点,生成一个 "二进制描述子"------ 描述子就是一串 0 和 1 的组合(比如 128 位、256 位),相当于给每个角点发一张 "身份证"。后续做图像匹配时,只要对比两张图中特征点的 "二进制身份证"(计算汉明距离:0 和 1 不同的位数),就能快速找到对应的特征点(比如左边图的角点 A,对应右边图的角点 A')。
(2)单词拆解:为什么叫 "BRIEF"?
- Binary:二进制 → 描述子是 0/1 串,不是传统的浮点数向量(占用内存小、匹配速度快)。
- Robust:鲁棒的 → 对光照变化、轻微噪声有抵抗力(比如图片亮一点 / 暗一点,描述子变化不大)。
- Independent:独立的 → 生成描述子的过程中,每个 0/1 位的判断是相对独立的。
- Elementary Features:基本特征 → 基于图像中最基础的灰度对比信息生成描述子。
(3)BRIEF 生成描述子的通俗原理
- 以 FAST 检测到的角点 P 为中心,取一个小的正方形区域(比如 31×31 像素);
- 在这个区域内,随机选 128 对像素点(比如 (x1,y1) 和 (x2,y2),128 对对应 128 位描述子);
- 对每一对像素:如果 (x1,y1) 的灰度值 > (x2,y2) 的灰度值,就记为 1,否则记为 0;
- 把 128 个 0/1 按顺序排列,就得到了这个角点的 BRIEF 描述子(比如 100101...01)。
(4)BRIEF 的缺点(为 ORB 的 "Rotated" 改进做铺垫)
BRIEF 虽然快、内存小,但同样没有「旋转不变性」:
- 如果图片旋转,角点周围的像素对位置会变,生成的 0/1 串会完全不同,导致匹配失败。
三、ORB 的核心改进:为什么要加 "Oriented" 和 "Rotated"?
ORB 解决了 FAST 和 BRIEF 的致命缺点,让算法具备「旋转不变性」和「尺度不变性」
1. 对 FAST 加 "Oriented"(带方向)
- 问题:FAST 检测的角点没有方向,图片旋转后无法识别;
- 改进:给每个角点计算「主方向」------ 通过统计角点周围像素的梯度方向(比如明暗变化的方向),找到出现次数最多的方向,作为角点的 "主方向";
- 效果:不管图片怎么旋转,角点的 "主方向" 会跟着调整,算法始终能识别出同一个角点。
2. 对 BRIEF 加 "Rotated"(旋转后)
- 问题:BRIEF 描述子没有旋转不变性,图片旋转后描述子完全不同;
- 改进:根据角点的 "主方向",把 BRIEF 用于对比的「随机像素对」也旋转相同的角度,再生成描述子;
- 效果:图片旋转后,描述子依然保持一致,匹配成功率大幅提升。
3. 额外改进:尺度不变性
- 问题:FAST 只能检测固定尺度的角点,图片放大 / 缩小后无法识别;
- 改进:构建「图像金字塔」(把图片按不同比例缩放,形成一系列不同尺度的图片),在每个尺度的图片上都检测角点;
- 效果:不管图片是放大还是缩小,都能检测到对应的角点。
四、总结:ORB 的核心逻辑链(一句话记牢)
用 "图像金字塔 + 主方向" 改进 FAST → 得到有尺度 / 旋转不变性的角点;再用角点主方向旋转 BRIEF 的像素对 → 得到有旋转不变性的二进制描述子;最终形成 "检测 + 描述" 一体化的高效局部特征算法。
五、应用场景(知道怎么用,更易理解)
- SLAM:比如无人机、机器人的定位与地图构建(ORB-SLAM 是经典算法,核心就是 ORB 特征);
- 目标跟踪:比如视频中跟踪一个物体(比如跟踪行人、车辆);
- 图像拼接:比如把多张风景照拼成全景图;
- 图像匹配:比如从一堆图片中找到包含某个目标的图片(比如找包含 "猫" 的图片)。
(3) ORB 算法流程(逐步详解)
3.1 构建图像金字塔(scale-space)
-
构造多层图像金字塔(例如 8 层),每层是上一层按
scaleFactor缩小(常用 1.2)。 -
在每层分别检测关键点,这样可以对尺度变化有一定适应(不是完全尺度不变,但足够工程使用)。
3.2 FAST 检测关键点(角点)
-
在每个金字塔层使用 FAST(或改良的 FAST)检测角点。
-
FAST 给出很多候选点,ORB 还对这些点进行非极大值抑制(NMS),保留局部响应最大的点。
3.3 给关键点计算"主方向"(orientation)
ORB 使用 图像灰度质心法(intensity centroid)为每个关键点计算方向,步骤大致为:
-
在关键点周围取一个固定大小的圆形邻域(patch),计算灰度加权质心相对于关键点的向量。
-
质心向量的角度就是该关键点的方向 θ。
-
这个方向用于"旋转对齐"后再计算描述子,从而获得旋转不变性。
(也有其他方法,比如基于梯度,但 ORB 使用质心方法速度快且效果不错)
3.4 生成 BRIEF 描述子并"旋转"它(Oriented BRIEF)
-
BRIEF 的核心是事先定义一组像素对 (p_i, q_i) 在 patch 中(例如 256 对),比较这两个像素的灰度:若 I(p_i) < I(q_i) 则该位为 1 否则为 0。把所有位串联形成一个二进制描述子(例如 256 位 -> 32 字节)。
-
为了让 BRIEF 对旋转不敏感,ORB 对这些像素对做"旋转变换"(用关键点方向 θ 旋转原先的采样点对),再按旋转后的像素对来比较灰度 -> 得到 Oriented BRIEF。
3.5 描述子选择与排序(质量筛选)
-
ORB 对候选关键点根据 Harris 响应 或 FAST 得分(可以选择)排序,选出前 N 个最稳定关键点(参数
nfeatures)。 -
描述子通常是二进制的,用 Hamming 距离做相似度衡量(位异或后计 1 的个数)。
4) ORB 的关键参数(OpenCV 里常见)与含义
(OpenCV 的 cv2.ORB_create() 接受这些参数)
-
nfeatures:想要保留的关键点数量(例如 500, 1000, 2000)。越多越慢,占用越多内存,但提高鲁棒性。 -
scaleFactor:金字塔层之间的缩放比例(常用 1.2)。较小值 -> 更多层 -> 更好尺度覆盖但更慢。 -
nlevels:金字塔层数(常用 8)。 -
edgeThreshold:关键点不能靠边太近(以避免 patch 越界),默认 31。 -
firstLevel:金字塔第一层(一般 0)。 -
WTA_K:BRIEF 中每个位比较时使用的采样点数,常用 2 或 3。若为 2 则为传统两点比较;更大能提高区分度。 -
scoreType:关键点分数类型,HARRIS_SCORE(用 Harris 角点响应)或FAST_SCORE(fast 的原生得分)。 -
patchSize:描述子 patch 的大小(默认 31)。 -
fastThreshold:FAST 检测的阈值(默认 20 左右),影响关键点多少。阈值低 -> 更多关键点但更嘈杂。
5) 匹配与距离度量
-
描述子是二进制 -> 使用 Hamming 距离 (位异或后计 1)。OpenCV 的
BFMatcher(cv2.NORM_HAMMING)。 -
若数据很大,可用基于 LSH 的 FLANN 近似匹配(FLANN + LSH 支持二进制描述子)。
6) ORB 在图像分类中的使用(完整管线)
局部特征本身更多用于匹配、检索,但也能用于分类。最常见的是 Bag-of-Visual-Words (BoW) 或 Fisher Vector。下面是完整流程(BoW + SVM):
步骤概览
-
关键点与描述子提取
对训练集中每张图像用 ORB 提取若干描述子(每个描述子例如 256 位)。
-
构建视觉词典(codebook)
把所有训练图片的描述子收集起来(可能很多),对这些描述子做聚类(例如 k-means)得到 K 个簇心(visual words),K 常见 64, 128, 256, 512。
-
向量量化(quantize)/编码
对每张图像,将其描述子映射到最近的簇心,然后统计每个簇心出现次数,得到长度 K 的直方图(即 BoW 特征)。
-
归一化与可选加权
对直方图做 L1 或 L2 归一化,或 TF-IDF 加权。
-
分类器训练
用 SVM(线性或核)或随机森林等对 K 维特征训练分类器。
-
预测时
对测试图像同样提取描述子、量化成直方图、归一化,然后送入训练好的分类器输出类别。
为什么这样做?
局部特征能捕捉物体的局部结构(比如椅子腿、电视边框),BoW 把每张图像表示为"视觉单词的频率分布",从而把局部信息汇总为全局、可分类的向量。
7) 伪代码 + 简单 Python/OpenCV 流程(可直接放到汇报里)
提取 ORB 描述子(单张图像)
python
import cv2
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
orb = cv2.ORB_create(nfeatures=1000, scaleFactor=1.2, nlevels=8)
keypoints, descriptors = orb.detectAndCompute(img, None)
# descriptors: numpy array, shape = (num_keypoints, descriptor_length_bytes)
descriptors 的 dtype 通常是 uint8,descriptor_length_bytes = 32(如果使用 256 位描述子则为 32 字节)。
建视觉词典(kmeans)
python
from sklearn.cluster import MiniBatchKMeans
import numpy as np
# 假设 all_desc 是 (N_total_descriptors, D) 的 numpy 数组
k = 256
kmeans = MiniBatchKMeans(n_clusters=k, batch_size=10000).fit(all_desc)
vocab = kmeans.cluster_centers_
把图像的描述子映射成 BoW 直方图
python
def bow_histogram(descriptors, kmeans):
if descriptors is None or len(descriptors)==0:
return np.zeros(kmeans.n_clusters)
labels = kmeans.predict(descriptors) # assign each descriptor to cluster
hist, _ = np.histogram(labels, bins=np.arange(kmeans.n_clusters+1))
hist = hist.astype(float)
hist /= (np.linalg.norm(hist) + 1e-8) # L2 normalize
return hist
用 SVM 分类
python
from sklearn.svm import SVC
clf = SVC(kernel='linear')
clf.fit(X_train_histograms, y_train)
y_pred = clf.predict(X_test_histograms)
8) 可视化与调试技巧(汇报中很加分)
-
在图像上画出关键点(OpenCV 的
cv2.drawKeypoints)来展示 ORB 找到的点分布。 -
显示某张图像的 BoW 直方图(条形图),对比不同类别的典型 histogram。
-
显示几个典型的 visual words(把落在同一簇的 patch 切出来拼接),让听众直观理解"视觉词"是什么。
-
展示匹配对(两个图像之间的 ORB 匹配线)来说明 ORB 对局部结构的识别能力。
9) ORB 的优点与缺点(在汇报里要讲清楚)
优点
-
速度快:FAST 和二进制 BRIEF 非常快,适合实时应用。
-
内存与计算轻:描述子小,匹配用 Hamming 距离,运算快。
-
免费/非专利:不像 SIFT/SURF 有专利问题(历史上)。
-
对旋转有一定不变性(因为有方向估计)。
缺点 / 局限
-
尺度不变性有限:通过金字塔缓解,但不如 SIFT 强。
-
对极端光照变化或模糊敏感:二进制比较对噪声敏感。
-
描述子判别力低于 SIFT(浮点描述子):二值化使得在复杂场景下区分能力下降。
-
对重复纹理或低纹理图像表现弱(没有足够角点)。
-
不是"端到端"的语义特征:比不上 CNN 在语义区分上的表现,尤其是类别间差异细微时。