首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >揭秘OpenCV4中多数人未知ORB与SIFT特征匹配技巧

揭秘OpenCV4中多数人未知ORB与SIFT特征匹配技巧

作者头像
OpenCV学堂
发布2026-04-02 18:21:44
发布2026-04-02 18:21:44
1470
举报
ORB与SIFT特征描述子

ORB(Oriented FAST and Rotated BRIEF)是一种快速关键点定位与特征描述子提取算法。它结合了FAST角点检测器和旋转不变的BRIEF描述符。FAST用于快速检测兴趣点,而BRIEF则提供了一种高效的方式来描述这些点的局部特征。为了实现旋转不变性,ORB在生成BRIEF描述子时考虑了关键点的方向。

SIFT(Scale-Invariant Feature Transform)特征描述子是一种特征提取方法,能够在不同尺度下检测和描述图像中的关键点的提取,并生成描述子。主要有以下四个步骤:

代码语言:javascript
复制
1. 尺度空间构建:通过构建高斯金字塔来寻找在不同尺度
   下的稳定关键点。
2. 关键点定位:精确定位关键点的位置和尺度,排除低对
   比度的点和边缘响应强的点。
3. 方向指派:计算每个关键点的主方向,使特征具有旋转不变性。
4. 描述子生成:在关键点周围区域生成16x16的窗口,分成4x4的小方块,
   计算每个小方块的方向直方图,形成一个128维的特征向量。

SIFT能够提取出具有尺度不变性和旋转不变性的特征描述子。

OpenCV特征匹配算法支持

01

暴力匹配(Brute-Force Matcher):

暴力匹配是一种简单的最近邻搜索算法,它通过计算两个特征描述子之间的欧氏距离或汉明距离来找到最佳匹配。在OpenCV中, ORB特征与SIFT特征的暴力方式是不同的、原因是以为ORB特征数据是基于字节的,SIFT跟SURF特征是基于浮点数的。代码演示如下:

ORB + 暴力匹配+汉明距离

代码语言:javascript
复制
import cv2
# 加载图像和创建ORB检测器
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# 创建暴力匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
# 绘制前10个匹配结果
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('Matches', img_matches)
cv2.waitKey()

SIFT + 暴力匹配 + L2

代码语言:javascript
复制
import cv2
# 加载图像和创建SIFT检测器
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 创建暴力匹配器
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
# 绘制前10个匹配结果
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('Matches', img_matches)
cv2.waitKey()

02

FLANN匹配:

FLANN匹配器是一种高效的近似最近邻搜索算法,适用于大型数据集和高维特征。它通过建立索引和使用优化的搜索策略来提高匹配速度。在OpenCV中,ORB特征与SIFT特征的FLANN匹配也是不一样的,通常ORB是基于LSH、SIFT基于KNN或者KDTree。代码演示如下:

ORB + FLANN

代码语言:javascript
复制
import cv2
# 加载图像和创建ORB检测器
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)
orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
# 创建FLANN匹配器 - LSH
index_params = dict(algorithm=6, table_number =5, key_size=12)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
# 绘制前10个匹配结果
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('Matches', img_matches)
cv2.waitKey()

SIFT + FLANN

代码语言:javascript
复制
import cv2
# 加载图像和创建SIFT检测器
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 创建FLANN匹配器- KDTree
index_params = dict(algorithm=1, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
# 绘制前10个匹配结果
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('Matches', img_matches)
cv2.waitKey()

总结

ORB特征的暴力匹配支持汉明距离、FLANN匹配支持LSH;SIFT特征的暴力匹配支持L1与L2、FLANN匹配支持KNN、KDTree等。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档