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算法主要可以分成以下几个步骤:
-
构建高斯金字塔(Gaussian Pyramid)
- 对于给定的图像,首先通过对图像进行不同尺度的高斯模糊,构建一个高斯金字塔。这涉及到对原图像逐层进行模糊,每一层的尺度增大。通常,金字塔中的每一层是上一层的平滑图像。
-
构建差分高斯金字塔(Difference of Gaussian)
- 通过相邻的高斯图像层之间进行减法来计算差分高斯(DoG),该过程可以近似计算图像的拉普拉斯金字塔(Laplacian Pyramid)。
- 公式为:
![]()
3. 关键点检测
- 对于每个像素点,寻找极值点,即在当前尺度和相邻的尺度(上层和下层)中具有极大或极小值的点。具体步骤如下:
- 遍历图像的每个像素,检查其是否在其邻域内(包括尺度上和空间上)是最大或最小点。
- 一般使用3x3x3的邻域,即考虑9个临近像素的3个尺度。
4. 精确定位关键点
- 对检测到的关键点进行细化,以提高其定位精度。常用的方法是通过泰勒级数展开。即优化关键点的位置,利用Hessian矩阵或者主导方向计算来细化关键点的位置和尺度。
5. 选择主方向
- 为每个关键点分配一个或多个主方向,以使得描述符具有旋转不变性。
- 计算关键点周围一定半径内的梯度值,并确定主方向。
- 形成一个方向直方图,用于统计方向,并选择最大直方图峰值作为关键点的主方向。
6. 生成关键点描述符
- 在每个关键点的周围区域中,计算其特征描述符。通常,这个区域被划分为多个子区块,并在每个子区块内计算梯度方向和幅值。
- 将每个子块的梯度信息汇总,形成一个包含多维信息的特征向量。
7. 特征点匹配(可选)
- 利用上述计算得到的描述符,针对不同图像中的特征点进行匹配。通常采取欧几里德距离或二元汉明距离来计算描述符之间的相似度。
具体步骤
-
构建高斯金字塔:对图像进行多次高斯模糊,生成一系列不同尺度的图像。
-
计算差分高斯:通过相邻两层的高斯图像做差,提取出潜在的特征点。
-
找到极值点:例如,对于某个像素,比较它与相邻8个像素以及上面和下面的对应像素,如果它是最大的或最小的,则记为一个关键点。
-
关键点精确定位:利用插值方法进行位置微调,去除那些边缘响应较强或低对比度的关键点。
-
计算方向:统计关键点周围像素的梯度直方图,确定主要方向。
-
生成描述符:以关键点的主方向为基准,计算关键点周围小块的描述符。
-
匹配过程:对于每个图像的特征点,可以使用最近邻法或比例测试进行匹配。
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()

相关文章:
python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)角点检测
角点检测(Corner Detection)是计算机视觉和图像处理中重要的步骤,主要用于提取图像中的关键特征,以便进行后续的任务,比如图像匹配、物体识别、运动跟踪等。下面介绍几种常用的角点检测方法及其应用。 1. Harris角点检…...
费解的开关
费解的开关 你玩过“拉灯”游戏吗? 25 盏灯排成一个 55 的方形。 每一个灯都有一个开关,游戏者可以改变它的状态。 每一步,游戏者可以改变某一个灯的状态。 游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也…...
【机器学习】机器学习引领数学难题攻克:迈向未知数学领域的新突破
我的个人主页 我的领域:人工智能篇,希望能帮助到大家!!!👍点赞 收藏❤ 一、引言 在数学的浩瀚领域中,存在着诸多长期未解的难题,这些难题犹如高耸的山峰,吸引着无数数…...
Qt之QDjango-db的简单使用
QDjango是一款由C编写、依托于Qt库的Web开发框架,其设计理念受到了广受欢迎的Python框架Django的影响。这个项目旨在提供一个高效、灵活且易于使用的工具集,帮助开发者构建高质量的Web应用。其项目地址: https://gitcode.com/gh_mirrors/qd/qdjango&…...
缓存、数据库双写一致性解决方案
双写一致性问题的核心是确保数据库和缓存之间的数据同步,以避免缓存与数据库数据不同步的问题,尤其是在高并发和异步环境下。本文将探讨双写一致性面临的主要问题和解决方案,重点关注最终一致性。 本文讨论的是最终一致性问题 双写一致性面…...
SUnet: A multi-organ segmentation network based on multiple attention【医学图像分割】
一、论文信息 1.1、中文名称 名称:SUnet:基于多重注意力的多器官分割网络 1.2、论文关键词 医学图像分割、Transformer、注意力机制、高效特征融合模块 1.3、核心概述 本文提出了一种新颖有效的医学图像分割方法 SUnet,用于腹部和胸部的多…...
uniapp实现“到这儿去”、拨打电话功能
"到这儿去" 在 UniApp 中实现“到这儿去”的功能,即调起地图导航至指定位置,对于不同的平台(小程序、H5、App)有不同的处理方式。下面将简单介绍如何在这些平台上实现该功能,并讨论位置信息的获取。后面需求会用到,先来找一些相关资料,并不一定很准确,但也来…...
2025年入职/转行网络安全,该如何规划?网络安全职业规划
网络安全是一个日益增长的行业,对于打算进入或转行进入该领域的人来说,制定一个清晰且系统的职业规划非常重要。2025年,网络安全领域将继续发展并面临新的挑战,包括不断变化的技术、法规要求以及日益复杂的威胁环境。以下是一个关…...
【博客之星】2024年度个人成长、强化学习算法领域总结
📢在2025年初,非常荣幸能通过审核进入到《2024年度CSDN博客之星总评选》TOP300的年度评选中,排名40。这还是第一次来到这个阶段,作为一名博士研究生,还是备受鼓舞的。在这里我将以回顾的方式讲述一下这一年在CSDN中走过…...
HTML5 Canvas实现的跨年烟花源代码
以下是一份基于HTML5 Canvas实现的跨年烟花源代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">…...
使用通用预训练范式为 3D 基础模型铺平道路
大家读完觉得有帮助记得关注和点赞!!!,本次是英文需要英文功底扎实的阅读。 Abstract In contrast to numerous NLP and 2D vision foundational models, learning a 3D foundational model poses considerably greater challenge…...
SpringMVC (2)
目录 1. RequestMapping 注解介绍 2. RequestMapping 使用 3. RequestMapping与请求方式 3.1 RequestMapping 支持Get和Post类型的请求 3.2 RequestMapping 指定接收某种请求 3.3 GetMapping和PostMapping 4. 传参 4.1 通过查询字符串传参 4.2 在 Body 中传参 4.2.1 …...
【Vim Masterclass 笔记16】S07L32 + L33:同步练习09 —— 掌握 Vim 宏操作的六个典型案例(含点评课内容)
文章目录 S07L32 Exercise 09 - Macros1 训练目标2 操作指令2.1. 打开 macros-practice.txt 文件2.2. 练习1:将旧版 Python 代码转换为新版写法2.3. 练习2:根据列表内容批量创建 Shell 脚本2.4. 练习3:对电话号码作格式化处理2.5. 练习4&…...
爬楼梯问题(Leetcode 第70题)
爬楼梯问题(Leetcode 第70题) 问题描述 假设你正在爬楼梯。每次你可以爬 1 个或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。…...
6.5 正定矩阵
一、正定矩阵 这一节关注的是特征值都是正数的对称矩阵。如果对称使得矩阵很重要,那么这个额外的性质(所有的 λ > 0 \lambda>0 λ>0)会使得它更加的特殊。我们所说的特殊并不表示它稀有,特征值都是正数的对称矩阵几乎…...
verilog笔记1
1. 阻塞赋值 阻塞赋值,顾名思义即在一个 always 块中,后面的语句会受到前语句的影响,具体来说就是在同一个always 中,一条阻塞赋值语句如果没有执行结束,那么该语句后面的语句就不能被执行,即被“阻塞”。也…...
游戏引擎学习第81天
仓库:https://gitee.com/mrxiao_com/2d_game_2 或许我们应该尝试在地面上添加一些绘图 在这段时间的工作中,讨论了如何改进地面渲染的问题。虽然之前并没有专注于渲染部分,因为当时主要的工作重心不在这里,但在实现过程中,发现地…...
git系列之revert回滚
1. Git 使用cherry-pick“摘樱桃” step 1: 本地切到远程分支,对齐要对齐的base分支,举例子 localmap git pull git reset --hard localmap 对应的commit idstep 2: 执行cherry-pick命令 git cherry-pick abc123这样就会将远程…...
监控与调试:性能优化的利器 — ShardingSphere
在分布式数据库系统中,监控和调试是确保系统高效运行的关键。ShardingSphere 提供了多种监控和调试工具,帮助开发者实时跟踪和优化性能,识别瓶颈,进行故障排查,从而提升系统的稳定性和响应速度。本文将介绍如何使用 Sh…...
LLVM - 编译器前端 - 理解BNF(巴科斯-诺尔范式)
一:概述 BNF(Backus-Naur Form,巴科斯-诺尔范式)是一种用于描述上下文无关文法的形式语言,广泛应用于定义编程语言、协议和文件格式的语法规则。 下面是一小段类Pascal编程语言,这个编程语言就可以用BNF描述。用BNF描述编程语言的语法规则之后,就可以根据这个规则生成抽…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
