OpenCV-Python(30):Harris角点检测

news2025/1/21 2:51:31

目标

  • 理解Harris角点检测的概念
  • 掌握函数cv2.cornerHarris()、cv2.cornerSubPix()的用法

Harris算法原理

        通过前面的图像特征介绍,我们知知道了角点的一个特性:向任何方向移动变化都很大Chris_Harris Mike_Stephens 在1988 年的文章《A Combined  Corner and Edge Detector》中就已经提出了焦点检测的方法被称为Harris 角点检测。Harris角点检测算法基于图像中角点的局部特征,通过计算每个像素点的响应函数来确定是否为角点。其原理如下:

  1. 图像梯度计算:首先对灰度图像进行梯度计算,常用的方法是使用Sobel算子计算图像在x和y方向上的梯度。
  2. 自相关矩阵计算:对于每个像素点,根据其周围的梯度值计算自相关矩阵,即计算该点的x方向梯度的平方和、y方向梯度的平方和以及x方向梯度与y方向梯度的乘积。
  3. Harris响应函数计算:根据自相关矩阵计算Harris响应函数,其定义为R = det(M) - k * trace(M)^2,其中M为自相关矩阵,det(M)为其行列式,trace(M)为其迹,k为一个经验参数。
  4. 非极大值抑制:对于计算得到的响应函数图像,对于局部最大值点保留,其余点设为0,以消除重复检测的角点。
  5. 阈值化:根据设定的阈值,将响应函数图像中低于阈值的点排除,以得到最终的角点位置。

        Harris角点检测算法的基本思想是,角点处图像灰度变化明显,梯度方向变化也明显。因此,在角点处,自相关矩阵的特征值较大,而在非角点处,特征值较小。通过计算自相关矩阵的特征值来判断是否为角点,同时通过Harris响应函数的计算来量化角点的重要性。把这个思想换成数学形式,将窗口向各个方向移动(u,v)然后计算所有差异的总和。公式如下:

窗口函数可以是正常的矩形窗口也可以是对每一个像素给予不同权重的高斯窗口,角点检测中使E (μ, ν) 的值最大。就是必需要使方程右侧的第二项的取值最大。对上面的等式进行泰勒级数展开然后再进行几步数学换算(可以参考其他标准教材)我们得到下面的等式:

这里的 Ix 和Iy 是图像在x 和y 方向的导数。可以使用函数cv2.Sobel()计算得到。然后就是主要部分了。他们根据一个用来判定窗口内是否包角点的等式进行打分。 

 可以用下图来表示我们的结论:

        所以Harris角点检测的结果是一个由角点分数构成的灰度图像。选取适当的阈值对结果图像进行二值化我们就检测到了图像中的角点。 

Harris角点检测步骤 

        Harris角点检测是一种经典的图像处理算法,用于检测图像中的角点。角点是图像中局部区域的重要特征点具有很强的边缘信息。Harris角点检测算法通过计算图像中每个像素点的响应函数,来确定是否为角点。

以下是Harris角点检测的基本步骤:

1.灰度化:将彩色图像转换为灰度图像,以便进行后续处理。
2.计算图像梯度:使用Sobel等算子计算图像在x和y方向上的梯度。
3.计算梯度积方向矩阵:根据梯度计算每个像素点的自相关矩阵。
4.计算角点响应函数:对于每个像素点,根据自相关矩阵计算Harris响应函数。
5.非极大值抑制:在响应函数图像中,对于局部最大值点保留,其余点设为0。
6.阈值化:根据设定的阈值,将响应函数图像中低于阈值的点排除。
7.记录角点位置:根据阈值化后的响应函数图像,记录剩余点的位置,即为角点。

        Harris角点检测算法的优点是简单高效,可以在实时或近实时的应用中使用。它在计算机视觉、图像处理和模式识别等领域中广泛应用,例如特征匹配、目标跟踪、图像拼接等。

OpenCV中角点检测实现

        cv2.cornerHarris()函数是OpenCV中用于进行Harris角点检测的函数,其用法如下:

cv2.cornerHarris(src, blockSize, ksize, k, dst=None, borderType=None)

参数说明:

  • src:输入图像,灰度图像,数据类型为float32。
  • blockSize:角点检测中使用的邻域大小,一般为2、3、4等奇数,默认值为3。
  • ksize:Sobel算子的大小,一般为3,默认值为3。
  • k:Harris角点检测方程中的自由参数,一般取值为0.04到0.06,默认值为0.04。
  • dst:输出图像,与输入图像大小相同,数据类型为float32。
  • borderType:像素的边界模式,可选参数,默认值为cv2.BORDER_DEFAULT。

        该函数返回的dst图像是一个与输入图像大小相同的角点响应图像,其中每个像素点的值表示该点的Harris响应函数值。

使用示例:

import cv2
import numpy as np

# 读取图像并转换为灰度图像
image = cv2.imread('chessboard.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)

# 计算Harris角点响应图像,最后一个参数在0.04 到0.06之间
dst = cv2.cornerHarris(gray, 2, 3, 0.04)

#dst = cv2.dilate(dst,None)

# 对响应图像进行阈值化,得到角点位置
threshold = 0.01 * dst.max()
corners = np.where(dst > threshold)

# 在图像上标记检测到的角点
image[corners] = [0, 0, 255]  # 标记为红色

# 显示结果图像
cv2.imshow('Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在以上示例中,我们首先读取图像并将其转换为灰度图像,然后使用cv2.cornerHarris()函数计算Harris角点响应图像。接着,我们对响应图像进行阈值化,得到角点位置,并在原始图像上标记检测到的角点,最后显示结果图像。

 

亚像素级精确度的角点检测

        有时我们需要最大精度的􄎁角点检测。OpenCV 为我们提供了函数cv2.cornerSubPix(),它可以提供亚像素级别的角点检测。下面是一个例子。首先我们先找到Harris角点􈙽,然后将角点的重心传给这个函数进行修正。Harris 角点用红色像素标出,绿色像素是修正后的像素。在使用这个函数时我们需要定义一个迭代停止条件。当迭代次数达到或者精度条件满足后迭代就会停止。我们同样需要定义角点搜索的领域大小。

cv2.cornerSubPix()函数定义:

cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria)

参数说明:

  • image:输入图像,灰度图像,数据类型为float32。
  • corners:角点位置的数组,每个角点由一个二维坐标表示,数据类型为float32。
  • winSize:搜索窗口的大小,一般为二元组(width, height),默认值为(11, 11)。
  • zeroZone:死区的大小,一般为二元组(width, height),默认值为(-1, -1)。
  • criteria:角点搜索的停止准则,包含最大迭代次数和最大误差值。默认值为(30, 0.01)。

该函数会使用亚像素级别的优化方法,在指定的搜索窗口内对角点进行迭代搜索,以获得更精确的角点位置。

使用示例:

import cv2
import numpy as np

# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 计算Harris角点响应图像
dst = cv2.cornerHarris(gray, 2, 3, 0.04)

# 对响应图像进行阈值化,得到角点位置
threshold = 0.01 * dst.max()
corners = np.where(dst > threshold)

# 使用亚像素级别的角点精确定位
corners = np.float32(np.transpose(corners))
cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.01))

# 在图像上标记检测到的角点
for corner in corners:
    x, y = corner.ravel()
    cv2.circle(image, (x, y), 3, (0, 0, 255), -1)

# 显示结果图像
cv2.imshow('Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

        在以上示例中,我们首先读取图像并将其转换为灰度图像,然后使用cv2.cornerHarris()函数计算Harris角点响应图像。接着,我们对响应图像进行阈值化,得到角点位置,并将角点位置转换为float32类型的数组。然后,我们使用cv2.cornerSubPix()函数对角点进行亚像素级别的精确定位。最后,在原始图像上标记检测到的角点,并显示结果图像。

结果如下,为了方便查看我们对角点的部分进行了放大:

 

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

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

相关文章

【滑动窗口】C++算法:K 个不同整数的子数组

作者推荐 动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本 本题涉及知识点 滑动窗口 LeetCoe992 K 个不同整数的子数组 给定一个正整数数组 nums和一个整数 k,返回 nums 中 「好子数组」 的数目。 如果 nums 的某个子数组中不同整数的个数恰好为 …

【DevOps 工具链】日志管理工具 - 22种 选型(读这一篇就够了)

文章目录 1、简述2、内容分类3、归纳对比表(排序不分先后)4、日志管理主要目的5、日志管理工具 22种 详细(排序不分先后)5.1、ManageEngine EventLog Analyzer5.1.1、简介5.1.2、效果图5.1.3、日志管理架构5.1.4、EventLog Analyz…

进行VMware日志管理

随着公司转向虚拟化其 IT 空间,虚拟环境日志监控正在占据日志管理的很大一部分,除了确保网络安全外,虚拟机日志监控还有助于管理虚拟化工具,这是最复杂的任务之一。 对虚拟环境日志的监控分析 当今公司中最受欢迎的虚拟平台之一是 VMware。…

基于SSM的蛋糕甜品店管理系统的设计与开发论文

基于SSM的蛋糕甜品店管理系统的设计与开发 摘要 如今,科学技术的力量越来越强大,通过结合较为成熟的计算机技术,促进了学校、医疗、商城等许多行业领域的发展。为了顺应时代的变化,各行业结合互联网、人工智能等技术&#xff0c…

软件工程导论——(为什么要学习软件工程?软件工程能学到什么?如何学习软件工程?)

导论(引言): 1.为什么要学习软件工程? 软件工程知识并不只是项目管理可以用,同样适用于开发岗。比如开发也要做需求分析和架构设计,也要做计划。学习软件工程后也可以帮助开发人员更好的理解软件项目的整个…

Solidworks学习笔记

本内容为solidworks的学习笔记,根据自己的理解进行记录,部分可能不正确,请自行判断。 学习视频参考:【SolidWorks2018视频教程 SW2018中文版软件基础教学知识 SolidWorks自学教程软件操作教程 sw视频教程 零基础教程 视频教程】 h…

智能透明加密、半透明加密和落地加密的区别是什么?

智能透明加密、半透明加密和落地加密的主要区别如下: PC端访问地址: https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 保护对象和方式: 智能透明加密:系统根据预设的敏感数据特征,对正…

FindMy技术用于遥控器

遥控器已经悄然成为我们生活中的常客。无论是控制电视机的开关,调整音量,切换频道,还是控制空调的温度,调节灯光亮度,甚至远程操控智能家居设备,遥控器都为我们提供了极大的便利。 将遥控器与FindMy技术相结…

Linux:apache优化(2)—— 网页传输压缩

网页传输压缩 客户端在请求httpd服务器数据,httpd服务器在返回数据包给客户端时,先对返回的数据进行压缩,压缩之后再传输 作用:配置 Apache 的网页压缩功能,是使用 Gzip 压缩算法来对 Apache 服务器发布的网页内容进行…

冠赢互娱基于 OpenKrusieGame 实现游戏云原生架构升级

作者:力铭 关于冠赢互娱 冠赢互娱是一家集手游、网游、VR 游戏等研发、发行于一体的游戏公司,旗下官方正版授权的传奇类手游——《仙境传奇》系列深受广大玩家们的喜爱。基于多年 MMORPG 类型游戏的自研与运营经验,冠赢互娱正式推出了 2D M…

基于ssm的OA办公系统设计与实现+vue论文

摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统办公信息管理难度大,容错率低,管理…

听GPT 讲Rust源代码--src/tools(39)

File: rust/src/tools/rustfmt/src/config/config_type.rs 在Rust代码中,rust/src/tools/rustfmt/src/config/config_type.rs文件的作用是定义了与配置相关的数据结构和函数。 Config struct(配置结构体):该结构体用于存储rustfmt…

前后端分离架构的特点以及优缺点

文章目录 一、前后端不分离架构(传统单体结构)1.1 什么是前后端不分离1.2 工作原理1.3 前后端不分离的优缺点1.4 应用场景 二、前后端分离架构2.1 为什么要前后端分离2.2 什么是前后端分离2.3 工作原理2.4 前后端分离的优缺点 参考资料 一、前后端不分离架构(传统单体结构) 首…

python测试工具: 实现数据源自动核对

测试业务需要: 现有A系统作为下游数据系统,上游系统有A1,A2,A3... 需要将A1,A2,A3...的数据达到某条件后(比如:A1系统销售单提交出库成功)自动触发MQ然后再经过数据清洗落到A系统,并将清洗后数据通过特定…

ElasticSearch 架构设计

介绍 ElasticSearchMySQLIndexTableDocumentRowFieldColumnMappingSchemaQuery DSLSQLaggregationsgroup by,avg,sumcardinality去重 distinctreindex数据迁移 ElasticSearch 中的一个索引由一个或多个分片组成 每个分片包含多个 segment(分…

【Spark精讲】一文讲透SparkSQL执行过程

SparkSQL执行过程 逻辑计划 逻辑计划阶段会将用户所写的 SQL语句转换成树型数据结构(逻辑算子树), SQL语句中蕴含的逻辑映射到逻辑算子树的不同节点。 顾名思义,逻辑计划阶段生成的逻辑算子树并不会直接提交执行,仅作为中间阶段 。 最终逻辑…

算法每日一题:参加考试的最大学生数 | 动态规划 | 状态压缩

大家好,我是星恒 今天的题目竟然是一道困难题目,看着就不简单,我们的目标是:理解如何做 学一些思路! 这次题目涉及的知识:动态规划,状态压缩(位运算) 给你一个 m * n 的…

挑战Python100题(8)

100+ Python challenging programming exercises 8 Question 71 Please write a program which accepts basic mathematic expression from console and print the evaluation result. 请编写一个从控制台接受基本数学表达式的程序,并打印评估结果。 Example: If the follo…

padStart(),padEnd()

今天获取当前时间的时候,gpt输出这样的代码,padStart(2, 0) function getCurrentDateFormatted() {const currentDate new Date();const month (currentDate.getMonth() 1).toString().padStart(2, 0);const day currentDate.getDate().toString().…

车载毫米波雷达及芯片新趋势研究1--毫米波雷达与其它车载传感器互补,研发及量产门槛较高

1.1 毫米波雷达是利用毫米波电磁波波束工作的雷达,车载是首要应用场景  毫米波雷达是一种以波长位于1-10mm、频率在30-300GHz的电磁波作为放射波的雷达传感器。  毫米波雷达利用毫米波波束进行工作。①检测障碍物时: 直接通过有无回波确认&#xff…