python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)角点检测

角点检测(Corner Detection)是计算机视觉和图像处理中重要的步骤,主要用于提取图像中的关键特征,以便进行后续的任务,比如图像匹配、物体识别、运动跟踪等。下面介绍几种常用的角点检测方法及其应用。

1. Harris角点检测

Harris角点检测是一种经典的角点检测算法,基于图像的局部特征,通过计算图像的自相关矩阵来判断一个点是否为角点。

  • 原理

    • 计算局部窗口内的图像梯度,并构造自相关矩阵。
    • 通过计算赫希因子(Harris Matrix),确定强度响应,响应值大于一定阈值的点被认为是角点。
  • 优点

    • 对于噪声具有一定的鲁棒性。
    • 可以检测到多种类型的角点。

OpenCV 中的 cv.cornerHarris() 函数用来实现 Harris 角点检测。它的参数是:

img - 输入图像,应为 float32 类型的灰度图。
blockSize - 角点检测所考虑的邻域大小。
ksize - Sobel 导数的内核大小。
k - Harris 检测器方程中的自由参数。

 OpenCV 带有一个函数 cv.cornerSubPix() ,它进一步细化了角点检测,以达到亚像素级精度。

import numpy as np
import cv2 as cv
filename = 'output.png'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# find Harris corners
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
dst = cv.dilate(dst,None)
ret, dst = cv.threshold(dst,0.01*dst.max(),255,0)
dst = np.uint8(dst)
# find centroids
ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst)
# define the criteria to stop and refine the corners
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria)
# Now draw them
res = np.hstack((centroids,corners))
res = np.intp(res)
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]] = [0,255,0]
cv.imshow('sobely',img)
cv.waitKey(0)

2. Shi-Tomasi角点检测

Shi-Tomasi角点检测法是对Harris方法的改进,更注重测量响应函数的特征。

  • 原理

    • 通过计算两个特征值,选择具有较大特征值的点作为角点。
    • 角点的选择更为简洁和高效。
  • 优点

    • 对图像旋转和尺度变化具有更好的鲁棒性。
    • 适合实时应用,如视频监控。

OpenCV 有一个函数, cv.goodFeaturesToTrack() 。它通过 Shi-Tomasi 方法(或 Harris 角点检测,如果你指定它)在图像中找到 N 个最佳的角点。输入图像应该是灰度图像。然后指定要查找的角点数量。然后指定质量等级,该等级是 0-1 之间的值,所有低于这个质量等级的角点都将被忽略。最后设置检测到的两个角点之间的最小欧氏距离。
例如尝试找到 25 个最佳角点:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('f:/apple.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
corners = cv.goodFeaturesToTrack(gray,25,0.01,10)
corners = np.intp(corners)
for i in corners:x,y = i.ravel()cv.circle(img,(x,y),3,255,-1)
plt.imshow(img),plt.show()

3. SIFT(尺度不变特征变换)

SIFT是一种用于检测和描述局部特征的算法,具有对尺度、旋转和光照变化的高鲁棒性。

  • 原理

    • 检测图像中多个尺度的关键点。
    • 生成每个关键点的描述符,以便进行特征匹配。
  • 优点

    • 高鲁棒性,适用于图像匹配、拼接等应用。
    • 可以处理遮挡和光照变化。

SIFT算法主要可以分成以下几个步骤:

  1. 构建高斯金字塔(Gaussian Pyramid)

    • 对于给定的图像,首先通过对图像进行不同尺度的高斯模糊,构建一个高斯金字塔。这涉及到对原图像逐层进行模糊,每一层的尺度增大。通常,金字塔中的每一层是上一层的平滑图像。
  2. 构建差分高斯金字塔(Difference of Gaussian)

    • 通过相邻的高斯图像层之间进行减法来计算差分高斯(DoG),该过程可以近似计算图像的拉普拉斯金字塔(Laplacian Pyramid)。
    • 公式为:

      3.  关键点检测

  • 对于每个像素点,寻找极值点,即在当前尺度和相邻的尺度(上层和下层)中具有极大或极小值的点。具体步骤如下:
    • 遍历图像的每个像素,检查其是否在其邻域内(包括尺度上和空间上)是最大或最小点。
    • 一般使用3x3x3的邻域,即考虑9个临近像素的3个尺度。

     4.  精确定位关键点

  • 对检测到的关键点进行细化,以提高其定位精度。常用的方法是通过泰勒级数展开。即优化关键点的位置,利用Hessian矩阵或者主导方向计算来细化关键点的位置和尺度。

   5. 选择主方向

  • 为每个关键点分配一个或多个主方向,以使得描述符具有旋转不变性。
    • 计算关键点周围一定半径内的梯度值,并确定主方向。
    • 形成一个方向直方图,用于统计方向,并选择最大直方图峰值作为关键点的主方向。

  6. 生成关键点描述符

  • 在每个关键点的周围区域中,计算其特征描述符。通常,这个区域被划分为多个子区块,并在每个子区块内计算梯度方向和幅值。
  • 将每个子块的梯度信息汇总,形成一个包含多维信息的特征向量。

  7. 特征点匹配(可选)

  • 利用上述计算得到的描述符,针对不同图像中的特征点进行匹配。通常采取欧几里德距离或二元汉明距离来计算描述符之间的相似度。

具体步骤

  1. 构建高斯金字塔:对图像进行多次高斯模糊,生成一系列不同尺度的图像。

  2. 计算差分高斯:通过相邻两层的高斯图像做差,提取出潜在的特征点。

  3. 找到极值点:例如,对于某个像素,比较它与相邻8个像素以及上面和下面的对应像素,如果它是最大的或最小的,则记为一个关键点。

  4. 关键点精确定位:利用插值方法进行位置微调,去除那些边缘响应较强或低对比度的关键点。

  5. 计算方向:统计关键点周围像素的梯度直方图,确定主要方向。

  6. 生成描述符:以关键点的主方向为基准,计算关键点周围小块的描述符。

  7. 匹配过程:对于每个图像的特征点,可以使用最近邻法或比例测试进行匹配。

import numpy as np
import cv2 as cv
img = cv.imread('f:/apple.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
kp = sift.detect(gray,None)
img=cv.drawKeypoints(gray,kp,img)
img=cv.drawKeypoints(gray,kp,img,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv.imshow('SIFT',img)
cv.waitKey(0)

4. SURF算法

SURF的基本理念是在SIFT的基础上,通过加快特征点检测和描述过程,取得更高的效率。SURF的主要步骤如下:

1.1 特征点检测
  • Hessian矩阵:SURF使用Hessian矩阵的行列式来检测特征点。通过计算每个像素点的Hessian矩阵,可以快速找到潜在的特征点。Hessian矩阵具有以下形式:

  • 盒子滤波:为了计算Hessian矩阵的行列式,SURF使用的是快速的Haar小波卷积。这种方法通过将图像分为不同大小的盒子,并使用加权和减少计算复杂度。
  • 梯度计算:SURF在特征点周围的邻域内计算图像的梯度值,并将其组织成一个描述符。描述符的生成过程涉及多个子块,各子块的特征会被汇总成一个固定长度的描述符。

  • 方向归一化:为了确保特征描述符具有方向不变性,SURF根据特征点的主方向进行方向归一化。

1.2 特征描述符生成
  • 梯度计算:SURF在特征点周围的邻域内计算图像的梯度值,并将其组织成一个描述符。描述符的生成过程涉及多个子块,各子块的特征会被汇总成一个固定长度的描述符。

  • 方向归一化:为了确保特征描述符具有方向不变性,SURF根据特征点的主方向进行方向归一化。


import cv2 as cv
from matplotlib import pyplot as plt# 读取图像
img = cv.imread('f:/apple.jpg', 0)# Create SURF object. You can specify params here or later.
# Here I set Hessian Threshold to 400
surf = cv.xfeatures2d.SURF_create(400)
# Find keypoints and descriptors directly
kp, des = surf.detectAndCompute(img,None)# Check present Hessian threshold
print( surf.getHessianThreshold() )# We set it to some 50000. Remember, it is just for representing in picture.
# In actual cases, it is better to have a value 300-500
surf.setHessianThreshold(50000)
# Again compute keypoints and check its number.
kp, des = surf.detectAndCompute(img,None)
print( len(kp) )img2 = cv.drawKeypoints(img,kp,None,(255,0,0),4)
plt.imshow(img2),plt.show()

5. ORB(Oriented FAST and Rotated BRIEF)

ORB结合了FAST特征检测和BRIEF特征描述,可以更快速地进行角点检测和描述。ORB 基本上是 FAST 特征点检测器和 Brief 描述子的融合,并进行了许多修改以增强性能。首先,它使用 FAST 查找特征点,然后应用 Harris 角点的测量方法来查找其中的前 N 个点。它还使用金字塔来生成多尺度特征。但有一个问题是,FAST 不计算方向。

  • 原理

    • 使用FAST算法检测特征点,计算点的方向和角度。
    • 采用BRIEF描述符来描述特征。
  • 优点

    • 快速高效,适合实时应用。
    • 对于图像的旋转具有稳健性。

cv.ORB()使用 feature2d 通用接口创建 ORB 对象。它有许多可选参数。
nFeatures,表示要保留的最大要素数量(默认为 500),
scoreType,  表示对特征点进行排序使用 Harris 得分或 FAST 得分(默认为 Harris 得分)等。
WTA_K, 决定生成一个 oriented BRIEF 描述子的所用的像素点数目。默认情况下它是 2,即一次选择两个点。在这种情况下进行匹配,使用 NORM_HAMMING 距离。如果 WTA_K 为 3 或 4,则需要 3 或 4 个点来产生 BRIEF 描述子,匹配距离由 NORM_HAMMING2 定义。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('f:/apple.jpg',0)
# Initiate ORB detector
orb = cv.ORB_create()
# find the keypoints with ORB
kp = orb.detect(img,None)
# compute the descriptors with ORB
kp, des = orb.compute(img, kp)
# draw only keypoints location,not size and orientation
img2 = cv.drawKeypoints(img, kp, None, color=(0,255,0), flags=0)
plt.imshow(img2), plt.show()

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

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

相关文章

QT开发-T113 Linux 主板QC配置套件

此篇文章用于记录在Linux主板上使用QT开发项目的套件配置步骤 进入QC软件,点击 Manage Kits… 选择项目对应的QT Version : 一般有一个项目对应的qmake 文件,选择导入即可 如果首次导入提示 qmake could not be added 需要先对项目进行命令行编译(具体命…

【云岚到家】-day03-门户缓存实现实战

【云岚到家】-day03-门户缓存实现实战 1.定时任务更新缓存 1.1 搭建XXL-JOB环境 1.1.1 分布式调度平台XXL-JOB介绍 对于开通区域列表的缓存数据需要由定时任务每天凌晨更新缓存,如何实现定时任务呢? 1.使用jdk提供的Timer定时器 示例代码如下&#xf…

SuperdEye:一款基于纯Go实现的间接系统调用执行工具

关于SuperdEye SuperdEye是一款基于纯Go实现的间接系统调用执行工具,该工具是TartarusGate 的修订版,可以利用Go来实现TartarusGate 方法进行间接系统调用。 该工具的目标是为了扫描挂钩的NTDLL并检索Syscall编号,然后使用它来执行间接系统调…

Python+ tkinter实现小学整数乘法和除法竖式演算式

Python tkinter实现小学整数乘法和除法竖式演算式 整数的乘法与除法是小学数学中的重要内容,它们是数学运算中的基础部分。 本文将使用python 和Python 的标准 GUI(图形用户界面)包tkinter,实现整数乘法与除法的竖式演示。供有兴趣…

线程池遇到未处理的异常会崩溃吗?

线程池中的 execute 和 submit 方法详解 目录 引言execute 方法 使用示例代码 submit 方法 2.1 提交 Callable 任务2.2 提交 Runnable 任务 遇到未处理异常 3.1 execute 方法遇到未处理异常3.2 submit 方法遇到未处理异常 小结 引言 在多线程编程中,线程池是提高性…

MongoDB基本操作

一、实验目的 1. 熟悉MongoDB的基本操作,包括CRUD(增加、读取、更新、删除)。 2. 理解MongoDB的文档型数据库特性和Shell的使用。 3. 培养学生通过命令行操作数据库的能力。 4. 强化数据库操作的实际应用能力。 二、实验环境准备 1.…

【银河麒麟高级服务器操作系统】业务访问慢网卡丢包现象分析及处理过程

了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:product.kylinos.cn 开发者专区:developer.kylinos.cn 文档中心:document.kylinos.cn 交流论坛:forum.kylinos.cn 服务器环境以及配置 【内核版本…

Kotlin Bytedeco OpenCV 图像图像54 透视变换 图像矫正

Kotlin Bytedeco OpenCV 图像图像54 透视变换 图像矫正 1 添加依赖2 测试代码3 测试结果 在OpenCV中,仿射变换(Affine Transformation)和透视变换(Perspective Transformation)是两种常用的图像几何变换方法。 变换方…

【LeetCode100】--- 寻找重复数

题目传送门 方法一:暴力解法(超时) 算法原理 双重循环,每次固定一个数,再遍历别的数。比较这两个数是否相等, 若相等则返回这个数。就是重复数。 复杂度分析 时间复杂度:O(N方&…

RabbitMQ---TTL与死信

(一)TTL 1.TTL概念 TTL又叫过期时间 RabbitMQ可以对队列和消息设置TTL,当消息到达过期时间还没有被消费时就会自动删除 注:这里我们说的对队列设置TTL,是对队列上的消息设置TTL并不是对队列本身,不是说队列过期时间…

mysql查看binlog日志

mysql 配置、查看binlog日志: 示例为MySQL8.0 1、 检查binlog开启状态 SHOW VARIABLES LIKE ‘log_bin’; 如果未开启,修改配置my.ini 开启日志 安装目录配置my.ini(mysql8在data目录) log-binmysql-bin(开启日志并指定日志前缀&#xff…

【QT】 控件 -- 按钮类(Button)

🔥 目录 1. 前言 2. Push Button 按钮 1、带有图标的按钮 -- 纯代码实现2、带有快捷键的按钮 -- 图形化&代码实现 3、按钮的重复触发 3. Radio Button 按钮 **1. click、press、release、toggled 的区别** **2. 单选框分组** 4. Check Box 复选 5. Tool Butto…

postman请求参数化

postman界面介绍 一、使用环境变量(Environment Variables)进行参数化 1、在请求中使用环境变量 在请求的url、请求头(Headers)、请求体(Body)等部分都可以使用环境变量。 URL 部分示例 点击 Postman 界面右上角的 “眼睛” 图标(Environment Quick Look)打开环境管理…

在 Babylon.js 中使用 Gizmo:交互式 3D 操作工具

在 3D 应用程序中,交互式操作对象(如平移、旋转、缩放)是一个常见的需求。Babylon.js 提供了一个强大的工具——Gizmo,用于在 3D 场景中实现这些功能。本文将介绍如何在 Babylon.js 中使用 Gizmo,并展示如何通过代码实…

虚幻商城 Fab 免费资产自动化入库

文章目录 一、背景二、实现效果展示三、实现自动化入库一、背景 上一次写了个这篇文章 虚幻商城 Quixel 免费资产一键入库,根据这个构想,便决定将范围扩大,使 Fab 商城的所有的免费资产自动化入库,是所有!所有! 上一篇文章是根据下图这部分资产一键入库: 而这篇文章则…

Ubuntu 22.04.5 修改IP

Ubuntu22.04.5使用的是netplan管理网络,因此需要在文件夹/etc/netplan下的01-network-manager-all.yaml中修改,需要权限,使用sudo vim或者其他编辑器,修改后的内容如下: # Let NetworkManager manage all devices on …

通过学习更多样化的生成数据进行更广泛的数据分发来改进实例分割

大家读完觉得有帮助记得关注和点赞!!! 本次使用的英文整理的一些记录,练习一下为后续SCI发表论文打好基础 Improving Instance Segmentation by Learning Wider Data Distribution with More Diverse Generative Data Abstract In…

写作利器:如何用 PicGo + GitHub 图床提高创作效率

你好呀,欢迎来到 Dong雨 的技术小栈 🌱 在这里,我们一同探索代码的奥秘,感受技术的魅力 ✨。 👉 我的小世界:Dong雨 📌 分享我的学习旅程 🛠️ 提供贴心的实用工具 💡 记…

通过Ukey或者OTP动态口令实现windows安全登录

通过 安当SLA(System Login Agent)实现Windows安全登录认证,是一种基于双因素认证(2FA)的解决方案,旨在提升 Windows 系统的登录安全性。以下是详细的实现方法和步骤: 1. 安当SLA的核心功能 安…

基于Python的多元医疗知识图谱构建与应用研究(上)

一、引言 1.1 研究背景与意义 在当今数智化时代,医疗数据呈爆发式增长,如何高效管理和利用这些数据,成为提升医疗服务质量的关键。传统医疗数据管理方式存在数据孤岛、信息整合困难等问题,难以满足现代医疗对精准诊断和个性化治疗的需求。知识图谱作为一种知识表示和管理…