OpenCV 入门到精通 09】特征检测与匹配:从 Harris 到 ORB 图像配准

【OpenCV 入门到精通 09】特征检测与匹配:从 Harris 到 ORB 图像配准

标签 :OpenCV 特征检测 ORB SIFT 特征匹配 Harris

难度 :⭐⭐⭐ | 阅读时长 :约 70 分钟 | 系列 :第 09/12 集

前置 :08 边缘与轮廓 | 下一集 :10 视频分析


写在前面

「怎么判断两张图是不是同一个场景?」「怎么把一张小图贴到另一张大图的正确位置?」答案在于 特征点 ------图像中稳定、可区分的「关键点」。本集对应官方 第5章 特征检测与描述。


本集学习目标

  • 理解特征点与描述子的概念
  • 使用 Harris 角点和 ORB 特征检测
  • 进行特征匹配和单应性变换
  • 完成图像拼接/物体查找实战

文章目录

  • [【OpenCV 入门到精通 09】特征检测与匹配:从 Harris 到 ORB 图像配准](#【OpenCV 入门到精通 09】特征检测与匹配:从 Harris 到 ORB 图像配准)
    • 写在前面
    • 本集学习目标
    • [9.1 什么是特征](#9.1 什么是特征)
    • [9.2 Harris 角点检测](#9.2 Harris 角点检测)
    • [9.3 ORB 特征检测](#9.3 ORB 特征检测)
    • [9.4 特征匹配](#9.4 特征匹配)
    • [9.5 单应性变换与物体查找](#9.5 单应性变换与物体查找)
    • [9.6 特征算法对比](#9.6 特征算法对比)
    • [9.7 踩坑指南](#9.7 踩坑指南)
    • [9.8 本集小结](#9.8 本集小结)

9.1 什么是特征

好的特征应具备

特性 说明
可重复性 同一位置在不同条件下能检测到
独特性 能与其他区域区分
局部性 对遮挡有一定鲁棒性
可量化 可用描述子向量表示

特征 = 关键点 + 描述子

复制代码
关键点 (KeyPoint):  位置 (x,y)、尺度、方向
描述子 (Descriptor):  128/256/512 维向量,描述周围像素模式

9.2 Harris 角点检测

python 复制代码
import cv2
import numpy as np

img = cv2.imread("chessboard.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)

# Harris 角点
dst = cv2.cornerHarris(gray, blockSize=2, ksize=3, k=0.04)
dst = cv2.dilate(dst, None)
img[dst > 0.01 * dst.max()] = [0, 0, 255]  # 红色标记角点

cv2.imshow("Harris", img)
cv2.waitKey(0)
参数 说明
blockSize 邻域大小
ksize Sobel 核大小
k Harris 参数,通常 0.04~0.06

9.3 ORB 特征检测

ORB = Oriented FAST and Rotated BRIEF,免费开源,速度快。

SIFT/SURF 需 opencv-contrib-python;ORB 在标准版即可用。

python 复制代码
import cv2

img = cv2.imread("scene.jpg", 0)
orb = cv2.ORB_create(nfeatures=500)

keypoints, descriptors = orb.detectAndCompute(img, None)

# 绘制关键点
img_kp = cv2.drawKeypoints(img, keypoints, None, color=(0,255,0),
                            flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("ORB", img_kp)
cv2.waitKey(0)
python 复制代码
# SIFT(需 contrib 版)
sift = cv2.SIFT_create()
kp, des = sift.detectAndCompute(img, None)

9.4 特征匹配

python 复制代码
import cv2

img1 = cv2.imread("object.jpg", 0)
img2 = cv2.imread("scene.jpg", 0)

orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

# BF 暴力匹配
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)

# 绘制前 20 个最佳匹配
img_match = cv2.drawMatches(img1, kp1, img2, kp2, matches[:20], None,
                             flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow("Matches", img_match)
cv2.waitKey(0)

匹配器选择

匹配器 距离度量 适用
BFMatcher + HAMMING 汉明距离 ORB, BRIEF
BFMatcher + L2 欧氏距离 SIFT, SURF
FlannBasedMatcher 近似最近邻 大量特征时更快

比率测试(过滤差匹配)

python 复制代码
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
good = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good.append(m)

9.5 单应性变换与物体查找

在场景图中定位模板物体:

python 复制代码
import cv2
import numpy as np

MIN_MATCH = 10

if len(good) > MIN_MATCH:
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
    dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

    # 计算单应性矩阵
    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

    h, w = img1.shape
    pts = np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]]).reshape(-1,1,2)
    dst = cv2.perspectiveTransform(pts, M)

    scene_color = cv2.imread("scene.jpg")
    cv2.polylines(scene_color, [np.int32(dst)], True, (0,255,0), 3)
    cv2.imshow("Found", scene_color)
    cv2.waitKey(0)

9.6 特征算法对比

算法 速度 精度 专利 包
Harris 快 中 无 标准
FAST 很快 中 无 标准/contrib
ORB 快 较好 无 标准
BRIEF 很快 中 无 contrib
SIFT 慢 高 已过期 contrib
SURF 中 高 已过期 contrib

💡 推荐:学习用 ORB;高精度用 SIFT(contrib)。


9.7 踩坑指南

坑 解决
SIFT 找不到 安装 opencv-contrib-python
匹配太少 增加 nfeatures;换更好的图
findHomography 失败 确保 good matches > 10
描述子为 None 图像太简单,无特征点

9.8 本集小结

步骤 API
检测 ORB_create().detectAndCompute()
匹配 BFMatcher().match() / knnMatch()
筛选 比率测试 0.75
定位 findHomography() + perspectiveTransform()

← 第08集 第10集:视频分析 →

参考:5_1 理解特征 | 5_8 ORB | 5_10 单应性

相关推荐
人工智能技术咨询.4 小时前
具身智能中的世界模型训练
人工智能
LaughingZhu4 小时前
Product Hunt 每日热榜 | 2026-10-06
人工智能·深度学习·神经网络·搜索引擎·百度
AOI小白新手上路4 小时前
AOI 缺陷检测复现实操指南:Anomalib + MVTec AD(glass)与 YOLOv8 + NEU-DET 两条路线
人工智能·深度学习·yolo
henrylin99994 小时前
RD-AGENT 第一讲 · AI 因子工厂是怎么运转的
人工智能
高洁014 小时前
具身智能中的世界模型训练
人工智能·python·深度学习·机器学习·transformer
无线通信科研笔记4 小时前
IEEE TVT 2026 论文精读与完整复现|相位误差如何重塑近场 RIS 的幅相响应
论文阅读·人工智能·python·算法·论文笔记
Devlive 开源社区5 小时前
AuthX 正式更名 GrantForge:我们重新做了一遍权限管理系统
大数据·人工智能·架构
朝朝辞暮i5 小时前
VLA 系统学习第 1 课:VLA 到底在干什么?
人工智能·python·计算机视觉·vla
鲲穹AI种草5 小时前
AI 壁纸生成工具怎么选?鲲穹 AI 壁纸工具功能实测与横向对比
人工智能·壁纸生成工具
科技林总5 小时前
向量与重排模型
人工智能