(四)OpenCV——特征点检测与匹配

前言

特征点检测与匹配是计算机视觉中的基础技术,广泛应用于图像拼接、物体识别、三维重建、运动跟踪等领域。OpenCV 提供了多种特征检测与匹配算法的实现。

特征点检测与匹配是计算机视觉中的核心技术,广泛应用于多个领域。以下是其主要应用场景:

  1. 图像拼接(全景图生成):旅游摄影、卫星图像处理、医学图像拼接

  2. 图像修复与增强:老照片修复、艺术品数字化

  3. 产品质量检测:电子元件检测、包装完整性检查

  4. 自动光学检测(AOI):PCB板检测、液晶面板检测

  5. 运动目标跟踪:智能监控、交通流量分

  6. 人脸识别与验证:门禁系统、移动支付

常用算法:

特征点检测:

  • Harris 角点检测

  • Shi-Tomasi 角点检测

  • SIFT

  • SURF

  • ORB

特征匹配:

  • BFMatcher (暴力匹配)

  • FLANN 匹配器

一、角点

通常意义上来说,角点就是极值点,即在某方面属性特别突出的点,是在某些属性上强度最大或者最小的孤立点、线段的终点。 对于图像而言,如图所示圆圈内的部分,即为图像的角点,其是物体轮廓线的连接点。

角点是指图像中各个方向上灰度变化都非常剧烈的点,具有以下特点:

  • 在两个正交方向上都有明显的梯度变化

  • 是图像中边缘的交点

  • 局部窗口内无论向哪个方向移动,图像灰度都会发生显著变化

角点检测算法基本思想是使用一个固定窗口(取某个像素的一个邻域窗口)在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。

二、Harris 角点检测

1. 基本思想

Harris角点检测基于一个核心观察:角点是图像中在各个方向上灰度变化都很剧烈的点。算法通过分析图像窗口在各个方向的移动引起的灰度变化来检测角点。

2.OpenCV实现

# harris角点检测
import cv2img = cv2.imread('../chess.png')# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Harris角点检测
# 参数说明:
# blockSize - 邻域大小
# ksize - Sobel算子孔径
# k - Harris检测器自由参数
dst = cv2.cornerHarris(gray, 2, 3, 0.04)# 角点展示
img[dst > 0.01 * dst.max()] = [0, 0, 255]cv2.imshow('Harris Corners', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 运行后的结果:

3.函数解析

def  cornerHarris(src, blockSize, ksize, k)

  1. blockSize

    • 邻域窗口大小

    • 值越大,检测的角点越"粗"

    • 典型值:2-5

  2. ksize

    • Sobel算子的孔径参数

    • 必须是奇数且≤31

    • 影响梯度计算的精度

    • 典型值:3或5

  3. k

    • Harris检测器的自由参数

    • 值越小,检测到的角点越多

    • 经验值范围:0.04-0.06

4.算法特点

优点

  1. 旋转不变性:角点旋转后仍能被检测

  2. 部分光照不变性:对均匀光照变化不敏感

  3. 计算效率高:适合实时应用

  4. 对噪声有一定鲁棒性(指该算法在图像存在噪声干扰的情况下,仍能相对稳定地检测出正确的角点位置,不会因小的噪声干扰而产生大量虚假角点或丢失真实角点)

缺点

  1. 不具有尺度不变性:图像缩放后可能检测不到相同角点

  2. 对阈值敏感:需要根据图像调整阈值参数

  3. 角点可能聚集:在纹理丰富区域可能检测到过多角点

三、Shi-Tomasi 角点检测

Shi-Tomasi角点检测方法是基于Harris角点检测的一种改进,它在多个方面提供了更好的性能和精度。Shi-Tomasi方法的核心思想是通过评估图像的最小特征值来识别角点。

1.OpenCV实现

# Shi-Tomasi角点检测(常用)
import cv2
import numpy as npimg = cv2.imread('../chess.png')# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Shi-Tomasi参数
corners = cv2.goodFeaturesToTrack(gray, 1000, 0.01, 10)# 转为整数
corners = np.int64(corners)# 绘制角点
for i in corners:x, y = i.ravel()cv2.circle(img, (x, y), 3, (0, 0, 255), -1)cv2.imshow('Shi-Tomasi Corners', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 运行后的结果:

 2.函数解析

def  goodFeaturesToTrack( src, maxCorners, qualityLevel, minDistance)

参数说明建议值
maxCorners表示最多可以检测到的角点数量,如果图像中存在更多角点,只保留质量最高的前 n 个。根据需求设定
qualityLevel角点质量阈值(相对最佳角点的比例),角点质量分数的最小值。只有质量高于该值的点才会被保留。值越小,保留的角点数量越多。0.01-0.1
minDistance角点间最小欧式距离,任意两个角点之间的像素距离必须大于该值,用于避免角点过于密集3-10像素

3.算法特点

优势

  1. 更直观的阈值设定:直接使用特征值,无需调整k参数

  2. 角点分布更均匀:通过minDistance参数控制

  3. 计算效率更高:避免计算完整的响应函数

劣势

  1. 对阈值的绝对依赖:qualityLevel需要根据图像调整

  2. 固定角点数量:可能遗漏部分角点

四、SIFT(尺度不变特征变换)

1.核心特征

  1. 尺度不变性

    • 通过高斯差分金字塔检测不同尺度的特征

    • 自动确定特征点所在的最佳尺度

  2. 旋转不变性

    • 基于局部梯度方向分配主方向

    • 描述符相对于主方向构建

  3. 光照鲁棒性

    • 使用梯度信息而非绝对灰度值

    • 对线性光照变化不敏感

2.OpenCV实现

这里我使用的版本是4.12,因为sift的专利已经过期,可以直接使用

import cv2img = cv2.imread('../chess.png')# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 创建sift对象
sift = cv2.SIFT_create()# 检测关键点与描述子
kp, des = sift.detectAndCompute(gray, None)# 绘制关键点
cv2.drawKeypoints(gray, kp, img)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果:

 
3.关键点与描述子

关键点

  • 本质:图像中具有显著特性的局部特征位置
  • 核心属性:空间信息(坐标、尺度(σ))、几何特性(主方向、响应强度)

描述子:记录了关键点周围对其有贡献的像素点的一组向量值,其不受仿射变换、光照变换等影响

 4.算法特性

优点:

  • 尺度不变性:在图像缩放±50%时仍能保持80%以上的特征重复率
  • 旋转不变性:图像旋转30°时匹配准确率>90%
  • 光照鲁棒性:对光照变化和对比度拉伸的抵抗能强
  • 高区分度描述子:128维向量提供丰富的特征信息

缺点:

  • 计算复杂度高
  • 对模糊敏感:模糊图像下的性能衰减
  • 边缘响应问题

五、SURF

SURF是SIFT算法的高效改进版本,在保持类似性能的同时显著提高了运算速度。

1.OpenCV实现

import cv2img = cv2.imread('../chess.png')# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 因为版权原因,不能使用
surf = cv2.xfeatures2d.SURF_create()# 检测关键点与描述子
kp, des = surf.detectAndCompute(gray, None)cv2.drawKeypoints(gray, kp, img)cv2.imshow('img', img)
cv2.waitKey(0)

运行后的结果:

2.与SIFT对比

特性SURFSIFT
计算速度快3-5倍较慢
描述符维度64/128维128维
尺度空间构建盒式滤波器+积分图像高斯金字塔
旋转不变性基于Haar小波响应统计梯度方向直方图
专利状态有专利(OpenCV需特殊编译)已过期
光照鲁棒性略优于SIFT优秀

六、ORB特征检测算法 

ORB(Oriented FAST and Rotated BRIEF)兼具实时性和良好匹配性能,可以做到实时检测。

1.OpenCV实现

# ORB特征检测
import cv2img = cv2.imread('../chess.png')# 转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 创建ORB对象
orb = cv2.ORB_create()kp, des = orb.detectAndCompute(gray, None)# 绘制关键点
cv2.drawKeypoints(gray, kp, img)cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行后的结果:

 

2.算法特点

优点:

  • 计算效率高
  • 旋转不变性改进
  • 尺度不变性(结合金字塔)
  • 二进制描述符:匹配时可通过汉明距离(异或运算)快速计算,适合硬件加速

缺点:

  • 对光照和噪声敏感:在光照剧烈变化或噪声较多时性能下降明显
  • 缺乏仿射不变性:在极端视角变化下匹配效果较差
  • 特征点分布不均
  • 描述符区分性有限:在高相似纹理或重复场景中易误匹配,需依赖后续筛选

七、对比特征点检测算法

算法速度尺度不变性旋转不变性光照鲁棒性适用场景
Harris静态角点检测(如标定板)
Shi-Tomasi需要稳定角点的场景
SIFT✔️✔️✔️高精度匹配(如全景拼接、3D重建)
SURF✔️✔️✔️实时性要求较低的鲁棒匹配
ORB✔️(金字塔)✔️(改进BRIEF)实时应用(SLAM、AR、移动端)

选择建议

  • 实时性优先:选 ORB(如无人机、移动端 AR)。

  • 精度优先:选 SIFT/SURF(如医学图像、三维重建)。

  • 简单角点检测:Harris/Shi-Tomasi(如标定、低动态场景)。

  • 平衡速度与鲁棒性:SURF 或 ORB + RANSAC 后处理。

八、BFMatcher (暴力匹配)

BFMatcher 是 OpenCV 中一种基于暴力搜索(Brute-Force)的特征匹配方法,通过计算所有特征点之间的相似度来寻找最佳匹配。它适用于各种特征描述符(如 SIFT、SURF、ORB、BRIEF 等),但计算复杂度较高,适合小规模特征匹配或精度要求高的场景。

BFMatcher 的核心思想是 穷举搜索,即对两组特征描述符进行两两比对,选择最相似的匹配对。

1.OpenCV实现

# 暴力特征匹配方法
import cv2img1 = cv2.imread('../opencv_search.png')
img2 = cv2.imread('../opencv_orig.png')# 转为灰度图
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)# 创建sift对象
sift = cv2.SIFT_create()# 检测关键点与描述子
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)# 暴力匹配
bf = cv2.BFMatcher(cv2.NORM_L1)
matches = bf.match(des1, des2)# 绘制关键点
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, None)cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果:

2.算法特点 

优点

✅ 高精度:暴力搜索确保找到全局最优匹配,适合对匹配质量要求高的场景(如 SIFT/SURF)。
✅ 灵活性:支持任意距离度量(如 NORM_L2 用于浮点描述符,NORM_HAMMING 用于二进制描述符)。
✅ 简单易用:OpenCV 提供直接接口,无需复杂参数调优。

缺点

❌ 计算复杂度高:时间复杂度为 ,大数据量时极慢。
❌ 内存消耗大:需存储所有特征点的距离矩阵,不适合实时或大规模匹配。

九、FLANN 匹配器

FLANN 是 OpenCV 中用于高效近似最近邻搜索的库,适用于大规模特征匹配(如 SIFT、SURF、ORB)。相比暴力匹配(BFMatcher),它通过空间分割(如 KD 树)层次聚类加速搜索,牺牲少量精度换取速度的大幅提升。

1.LANN 的核心原理

FLANN 通过以下两种主要方法加速最近邻搜索:

  1. KD 树(KD-Tree)

    • 适用于浮点型描述符(如 SIFT、SURF)。

    • 将特征空间递归划分为超矩形区域,搜索时跳过无关区域。

    • 需设置树的数量(trees=4)和搜索次数(checks=32)。

  2. 局部敏感哈希(LSH)

    • 适用于二进制描述符(如 ORB、BRIEF)。

    • 通过哈希函数将相似特征映射到相同桶中,减少比较次数。

    • 参数包括哈希表数量(table_number)和键值长度(key_size)。

2.OpenCV实现

# FLANN特征匹配
import cv2img1 = cv2.imread('../opencv_search.png')
img2 = cv2.imread('../opencv_orig.png')# 转为灰度图
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)# 创建sift对象
sift = cv2.SIFT_create()# 检测关键点与描述子
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)# flann
# FLANN索引的参数
index_params = dict(algorithm=1, trees=5)
# 搜索时的参数
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)# 对描述子进行匹配计算
matches = flann.knnMatch(des1, des2, k=2)# 筛选匹配
good = []
for i, (m, n) in enumerate(matches):if m.distance < 0.7 * n.distance:good.append(m)# 绘制关键点
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, [good], None, flags=2)cv2.imshow('img', img3)
cv2.waitKey(0)

 运行后的结果:

3. 算法特点

优点

✅ 速度快:比 BFMatcher 快 10~100 倍(尤其适合大规模数据)。
✅ 灵活性:支持浮点和二进制描述符,参数可调。
✅ 内存友好:索引结构优化,适合嵌入式设备或实时系统(如 SLAM)。

缺点

❌ 近似匹配:返回的结果是近似最优,可能遗漏真实最近邻。
❌ 参数敏感:需根据数据分布调整 treeschecks 等参数。

参考文献:

角点(corner point)、关键点(key point)、特征点(feature point)概念辨析_关键角点-CSDN博客

OpenCV快速入门:特征点检测与匹配_opencv特征点检测与匹配-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89544.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89544.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

if (a == 1 a == 2 a == 3)返回true的问题思考

引文&#xff1a; 无意中看到了这样的非常规逻辑&#xff0c;在想前后端应该都可以实现&#xff0c;a 是变量&#xff0c;或者操作a时触发了值得改变。 意义&#xff1a; 该问题让我们知道了一切规则都是可以被打破的&#xff0c;世界上的规则都是为了解释某种现象设计的。 题目…

MySQL的索引操作及底层结构浅析

一.索引提高数据库的性能&#xff0c;索引是物美价廉的东西了。不用加内存&#xff0c;不用改程序&#xff0c;不用调sql&#xff0c;只要执行正确的 create index &#xff0c;查询速度就可能提高成百上千倍。但是天下没有免费的午餐&#xff0c;查询速度的提高是以插入、更新…

stm32f4 dma的一些问题

文章目录前言一、使用开发板烧录dma代码不生效问题二、一个工程同时使用uart2、uart3借助dma来传递1.并行。2.DMA "同时工作"的本质3.总线访问的具体含义4.实际效果5.最佳实践5.1 总线传输机制&#xff1a;6.DMA传输中断的问题总结前言 记录一些使用stm32f4 dma过程…

登录功能实现深度解析:从会话管理到安全校验全流程指南

登录功能实现深度解析&#xff1a;从会话管理到安全校验全流程指南大家好&#xff0c;我是凯哥Java本文标签&#xff1a;登录验证流程、过滤器与拦截器、安全防护措施简介本文深入探讨了从登录功能实现到会话管理和安全校验的全流程&#xff0c;包括参数校验、身份验证、令牌生…

2023 年 5 月青少年软编等考 C 语言六级真题解析

目录 T1. 字符串插入 思路分析 T2. 机器翻译 思路分析 T3. 栈基本操作 思路分析 T4. 双端队列 思路分析 T1. 字符串插入 题目链接:SOJ D1138 有两个字符串 s t r str str 和 s u b s t r substr substr, s t r str str 的字符个数不超过 10 10 10, s u b s t r substr …

Redux架构解析:状态管理的核心原理

Redux 作为 JavaScript 应用的状态管理库&#xff0c;其技术架构与核心原理围绕​​可预测的状态管理​​设计&#xff0c;通过严格的单向数据流和函数式编程理念实现复杂应用的状态控制。以下从设计理念、核心架构、工作流程、源码实现等角度进行系统性剖析&#xff1a;一、设…

linux制作镜像、压缩镜像、烧录的方法

最近在玩香橙派的时候&#xff0c;需要搞多个板子&#xff0c;一个一个配环境也太麻烦了吧......于是通过搜索&#xff0c;发现可以把linux设备&#xff08;比如香橙派&#xff0c;树莓派等等&#xff09;制作为镜像&#xff0c;然后像烧录官方镜像一样烧进新的sd卡&#xff0c…

机械材料计算软件,快速核算重量

软件介绍 今天为大家推荐一款专为机械行业设计人员打造的金属材料重量计算软件&#xff0c;帮助工程师快速完成材料重量核算。 软件特点 这款绿色版计算工具体积小巧&#xff0c;不足100KB&#xff0c;无需安装即可直接运行&#xff0c;不占用系统资源&#xff0c;特别适…

Chrome更新后,扩展不能用问题

Chrome更新后&#xff0c;扩展不能用问题 此扩展程序不再受支持&#xff0c;因此已停用 在 Windows 10/11 搜索框中输入 regedit 打开 注册表编辑器 在注册表编辑器中打开&#xff1a;HKEYLOCALMACHINE\SOFTWARE\Policies\ 右键单击 Policies 新建项 命名为 Google 右键单…

【Python】通过cmd的shell命令获取局域网内所有IP、MAC地址,通过主机名获取IP

【Python】通过cmd的shell命令获取局域网内所有IP、MAC地址&#xff0c;通过主机名获取IP 更新以gitee为准&#xff1a; gitee 文章目录cmd命令获取IPping主机名获取IP的主机名socket获取当前网关运行效果附录&#xff1a;列表的赋值类型和py打包列表赋值BUG复现代码改进优化总…

sky-take-out项目Mybatis的使用

分页查询public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {PageHelper.startPage(categoryPageQueryDTO.getPage(),categoryPageQueryDTO.getPageSize());//下一条sql进行分页&#xff0c;自动加入limit关键字分页Page<Category> page categor…

H3CNE小小综合实验

实验拓扑图实验需求 按照图示配置IP地址在SW1和SW2之间配置链路聚合增加链路带宽&#xff0c;提高可靠性PC5和PC6属于VLAN10&#xff0c; PC7和PC8属于VLAN20SW1和SW2属于二层交换机&#xff0c;SW3为三层交换机&#xff08;VLAN100用于对接R4&#xff09;,在交换机之间相连的链…

IP协议深入理解

一、什么是ip协议?1.1、ip协议是网络层协议&#xff0c;ip协议的本质工作是提供一种能力&#xff0c;把数据可靠的跨网络从主机A送到主机B&#xff1b;1.2、什么是ip&#xff1f;ip目标网络目标主机&#xff1b;画图图解:如图&#xff0c;当主机A想要把数据发给主机B时&#x…

接收表单数据:serialize()函数解析

一、form-serialize作用与引入 作用&#xff1a; form-serialize可以快速收集表单数据&#xff0c;按照使用者意愿转化为对象或字符串输出&#xff0c;以便于提交至服务器。 引入&#xff1a; form-serialize不是浏览器自带的JS方法&#xff0c;而是第三方工具库。可以直接通过…

vc配置使用预编译

预编译原理 stdafx.h中加入系统文件&#xff0c;减少cpp中对这些文件的解析&#xff0c;提高速度 stdafx.h 会把编译的文件生成pch&#xff0c;后续解析头文件直接调用pch里面的数据 配置 新建stdafx.h和stdafx.cpp文件 配置stdafx.cpp文件为/Yc 创建预编译文件整个项目设置/Yc…

反射机制的登录系统

一、实体层&#xff08;po层&#xff09; //UserInfo package com.hugeyurt.po;import java.sql.ResultSet; import java.sql.SQLException;public class UserInfo {private String userID;private String name;private int count;private Long errorTime;private String pwd;p…

装饰器模式及优化

装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。这种模式创建了一个装饰器类&#xff0c;用来包装原有的类&#xff0c;并在保持类方法签名完整性的前提下&#xff…

共指消解技术全解析:从语言学规则到深度学习(附论文精读)

精读威斯康星大学综述《Coreference Resolution: A Survey》&#xff0c;揭秘NLP中"实体链接"的核心技术一、什么是共指消解&#xff1f;为什么它是NLP的基石&#xff1f;共指消解(Coreference Resolution) 旨在识别文本中指向同一实体的不同表述。例如&#xff1a;t…

git配置git commit -m “fix 11,22: 修改bugid为11,22“

文章目录前言一、报错提示二、实现1.commitlint.config.js规范配置2. **修改正则表达式**&#xff1a;3. **移除 scope-case 规则**&#xff1a;4. **增强自定义规则逻辑**&#xff1a;测试结果&#xff1a;正则表达式详解&#xff1a;前言 提示&#xff1a;正常的配置git规范…

nastools继任者?极空间部署影视自动化订阅系统『MediaMaster』

nastools继任者&#xff1f;极空间部署影视自动化订阅系统『MediaMaster』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 对于我们NAS玩家来说&#xff0c;观影总是大家绕不开的一个执念&#xff0c;并且为观影的折腾大家也都是乐此不疲~ 曾经有一个非常绝绝子的观影神器摆在我们…