本节摘要:SOURCE:SIFT 128 维梯度直方图;ORB 为 rotated BRIEF 二进制;HOG 为块梯度方向直方图(行人检测)。本节动手
compute描述子并比较 L2 vs Hamming 距离。
detectAndCompute 输出 shapeimport cv2 img = cv2.imread('patch.png', 0) sift = cv2.SIFT_create() kp, des = sift.detectAndCompute(img, None) print(len(kp), des.shape) # N x 128 float32
每个关键点 16×16 邻域分成 4×4 子块,每块 8 方向梯度直方图 → 128 维。
orb = cv2.ORB_create(nfeatures=500) kp2, des2 = orb.detectAndCompute(img, None) # des2: uint8, 32 bytes = 256 bit bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
ORB 免费可商用;SIFT 专利已过期(OpenCV 4.4+ 内置)。
方向梯度直方图按 cell/block 聚合 — Pedestrian Detection 经典特征。OpenCV:
hog = cv2.HOGDescriptor() # 常用于与 SVM 联用行人检测
| 描述子 | 维度 | 距离 | 特点 |
|---|---|---|---|
| SIFT | 128 float | L2 | 稳健、慢 |
| ORB | 32 byte | Hamming | 快 |
| HOG | 高维向量 | L2 | 全局形狀 |

drawKeypoints rich 看方向⚠️ 常见坑:对空白区域 detect — des 为空,匹配时报错。
💡 关键直觉:描述子把局部外观变成向量 — 匹配 = 向量近邻。
下一节匹配与拼图应用。
检测器回答了"在哪",描述子回答"长什么样"。描述子把关键点附近的局部外观编码成数值向量,要求同一物理点在视角变化下描述子尽量接近、不同点之间尽量可分。SIFT 描述子:以关键点方向为基准,把 16×16 邻域划分成 4×4 子块,每个子块统计 8 个方向的梯度直方图,共 4×4×8=128 维。以关键点方向为基准做坐标旋转,实现了旋转不变;用梯度方向直方图而非原始像素,对光照变化相对鲁棒。匹配时用欧氏距离(L2),最近邻就是最相似的点。
import cv2 # 描述子与关键点一起输出 sift = cv2.SIFT_create() kp, des = sift.detectAndCompute(img, None) # des 形状 N x 128,float32,每行是一个关键点的描述子 print(des.shape)
ORB 用 BRIEF 的思路:在关键点周围随机选 N 对像素(按高斯分布采样),比较每对像素的亮度,亮的一侧记为 1、暗的记 0,拼成二进制串(32 字节 = 256 位)。二进制描述子的好处是匹配快——用汉明距离(异或后数 1 的个数),位运算在硬件上极快。ORB 在生成描述子前用灰度质心方向做旋转补偿,让二进制描述子也具备旋转不变性。它的尺度不变性弱于 SIFT,但速度优势明显,是实时 SLAM 的主流选择。
HOG 与 SIFT 同源(都是梯度方向直方图),但组织方式不同:HOG 在固定网格的 cell 上统计梯度直方图,block 内归一化,滑窗整幅图,描述的是"整体形状",经典用途是行人检测(与 SVM 联用)。HOG 不做关键点检测,是密集描述子;SIFT/ORB 只在关键点处计算,是稀疏描述子。理解"密集 vs 稀疏"这个区别,就理解了 HOG 与 SIFT 的分工:一个描述区域形状,一个描述局部点。
评估描述子的标准:匹配准确率、对旋转/尺度/光照的鲁棒性、计算与匹配速度、专利与授权。工程选型经验:高精度离线匹配(三维重建、图像检索)用 SIFT;实时系统(SLAM、AR)用 ORB;需要整体形状语义用 HOG。SIFT 专利已过期,OpenCV 4.4 之后内置可用。匹配前的预处理也重要:对空白或低纹理区域,检测器可能输出零个关键点,调用匹配前先判断描述子是否为空,避免报错。
实验建议:对同一张图的两个尺度版本提取 SIFT 描述子,计算两组的距离矩阵,验证"对角线(真匹配)距离最小";再用 ORB 对比同图提取耗时与匹配耗时。这个实验能直观对比两种描述子的鲁棒性和速度差异。
一个理解要点:描述子向量在匹配时是"最近邻搜索",因此描述子的维度设计其实是在"信息量"和"计算量"之间平衡。128 维对梯度信息足够表达,32 字节二进制对实时匹配足够快,理解这个平衡视角,才能读懂各类描述子的设计取舍。
最后,描述子与深度学习特征的类比值得建立:CNN 的中间层特征本质也是"局部外观的向量化",只不过从手工设计变成数据学习。SIFT 的 128 维梯度直方图和 CNN 的特征向量,在"匹配 = 向量距离"这个抽象上是完全一致的。
补一个特征工程视角:描述子之间的比较,除了距离度量,还要考虑量化与索引。大规模图像检索里,几十万张图的描述子不可能逐对暴力匹配,通常先把描述子做视觉词典量化(每个描述子归属到最近的聚类中心),再用倒排索引加速检索,这就是 BoVW(词袋模型)的流程。近年来把描述子量化成紧凑的哈希码(Hamming 嵌入)也常用于移动端检索。理解"描述子只是原始向量,真正落地还要靠索引与量化",会让你的特征知识从算法层面延伸到工程层面。深度学习时代的特征检索(如 faiss)沿用同样的思路,只是特征来源变成了神经网络。