一键找出图像中物体的角点

server/2024/12/14 12:28:58/


✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨

🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。

我是Srlua小谢,在这里我会分享我的知识和经验。🎥

希望在这里,我们能一起探索IT世界的奥妙,提升我们的技能。🔮

记得先点赞👍后阅读哦~ 👏👏

📘📚 所属专栏:传知代码论文复现

欢迎访问我的主页:Srlua小谢 获取更多信息和资源。✨✨🌙🌙

​​

​​

目录

概述

算法原理

演示效果

核心逻辑

使用方式

基础镜像

配置环境

直接运行

更换图片运行

参考文献


 本文所有资源均可在该地址处获取。

概述

本文复现论文A COMBINED CORNER AND EDGE DETECTOR中提出的图像中的物体角点检测算法,也称Harris算法。原文连接https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=88cdfbeb78058e0eb2613e79d1818c567f0920e2

该论文所提出的角点检测算法是计算机视觉领域的经典算法,至今仍在计算机视觉领域有着广泛的应用。

该方法对算力几乎没有任何要求,依据图像邻域内灰度值的分布特点来对图像中各区域的角点进行判断。不像深度学习需要依靠大量数据的训练且对数据集分布有依赖性,所以时至今日依然在工业界有着很高的应用价值。

算法原理

正如边缘在灰度图像中在某一个方向上会出现明显的灰度变化,角点在图像中往往是在两个方向上都出现明显的灰度变化。


如在此图中,红点标注处的角点在两个箭头方向的垂直方向上都有明显的灰度变化,两个红色箭头标注出了它的两个灰度变换边缘。

假设我们现在要检测的图片为II,在图像处理中,能够充分体现图像灰度变化特征的是它的方向导数,IxIx​与IyIy​,分别代表图像II的水平方向导数与竖直方向导数。

Ix(i,j)=I(i,j+1)−I(i,j−1)2Ix​(i,j)=2I(i,j+1)−I(i,j−1)​

Iy(i,j)=I(i−1,j)−I(i+1,j)2Iy​(i,j)=2I(i−1,j)−I(i+1,j)​

Harris算法就是利用图像的方向导数制定了一个响应指标:

R=det(M)−k⋅trace(M)2R=det(M)−k⋅trace(M)2

个人感觉原文的公式不太好理解,以下我将按照我的理解对公式进行适当的改变。
对于R,实际上是一个R图,其尺寸与我们要检测的图像II一致,于是上面的相应指标实际上是每个像素都有一个相应指标,即:

R(i,j)=det(M(i,j))−k⋅trace(M(i,j))2R(i,j)=det(M(i,j))−k⋅trace(M(i,j))2

其中

M(i,j)=[A(i,j)B(i,j)B(i,j)C(i,j)]M(i,j)=[A(i,j)B(i,j)​B(i,j)C(i,j)​]

在用3X3邻域内的数据进行操作时,A(i,j)、B(i,j)、C(i,j)在原文中对应的定义应该是这样的:

A(i,j)=∑m=−11∑n=−11ω(m,n)Ix2(i+m,j+n)B(i,j)=∑m=−11∑n=−11ω(m,n)Ix(i+m,j+n)×Iy(i+m,j+n)C(i,j)=∑m=−11∑n=−11ω(m,n)Iy2(i+m,j+n)A(i,j)=m=−1∑1​n=−1∑1​ω(m,n)Ix2​(i+m,j+n)B(i,j)=m=−1∑1​n=−1∑1​ω(m,n)Ix​(i+m,j+n)×Iy​(i+m,j+n)C(i,j)=m=−1∑1​n=−1∑1​ω(m,n)Iy2​(i+m,j+n)

即对Ix2Ix2​、Iy2Iy2​和IxIyIx​Iy​三个方向导数图在3X3邻域内进行卷积得到A、B和C。
其中 ωω是高斯平滑核,主要是为了减少噪声对方向导数的影响。大多数情况下,ωω取一个全一矩阵就好。本方法也是采用了全一矩阵,所以以上定义可以修改为:

A(i,j)=∑m=−11∑n=−11Ix2(i+m,j+n)B(i,j)=∑m=−11∑n=−11Ix(i+m,j+n)×Iy(i+m,j+n)C(i,j)=∑m=−11∑n=−11Iy2(i+m,j+n)A(i,j)=m=−1∑1​n=−1∑1​Ix2​(i+m,j+n)B(i,j)=m=−1∑1​n=−1∑1​Ix​(i+m,j+n)×Iy​(i+m,j+n)C(i,j)=m=−1∑1​n=−1∑1​Iy2​(i+m,j+n)

所以RR指标的最终定义可以改为:

R(i,j)=Det⁡(M(i,j))−k(Tr⁡(M(i,j)))2=(A(i,j)C(i,j)−B(i,j)2)−k×(A(i,j)+C(i,j))2R(i,j)=Det(M(i,j))−k(Tr(M(i,j)))2=(A(i,j)C(i,j)−B(i,j)2)−k×(A(i,j)+C(i,j))2

其中k是一个经验参数,本算法中取0.02,当然也可以根据具体情况进行调整,通常来说k越大,算法对角点的判别就越严格,会有更少的点被判别为角点;k越小,算法的判别就越松一些,会有更多的点被判别为角点。

得到R图后,将R图中最大值RmaxRm​ax的0.2倍作为阈值。将R图中小于0.2Rmax0.2Rm​ax的像素坐标判别为是角点坐标,其余的则为非角点坐标,最终得到我们的结果图。

演示效果

Description

核心逻辑

def HarrisCornerDetector(image,k=0.02):
# 读取图像# 将图像转换为numpy数组I= imageI=np.array(I)sobel_x = np.array([[0, 0, 0], [-0.5, 0, 0.5], [0, 0, 0]])sobel_y=np.array([[0,0.5,0],[0,0,0],[0,-0.5,0]])# 对图像进行水平方向的卷积I_x = convolve2d(I, sobel_x, mode="same", boundary="symm")I_y=convolve2d(I,sobel_y,mode='same',boundary='symm')I2_x=I_x**2I2_y=I_y**2Ix_Iy=I_x*I_ysobel=np.array([[1,1,1],[1,1,1],[1,1,1]])A=convolve2d(I2_x,sobel,mode="same",boundary="symm")B=convolve2d(Ix_Iy,sobel,mode="same",boundary="symm")C=convolve2d(I2_y,sobel,mode="same",boundary="symm")R=(A*C-B**2)-k*(A+C)**2R_max=np.max(R[1:-1,1:-1])C=RC[C<=(0.2*R_max)]=0C[C>(0.2*R_max)]=1return C

使用方式

基础镜像

python:3.9.7

配置环境

解压后进入HarrisCornerDetector项目路径
运行以下命令:

pip install -r requirements.txt

直接运行

python main.py

即可看到视频中示例图片的角点检测效果。

更换图片运行

修改main.py文件里的默认图片路径


将"data/rice.png"更改为你自己的图片路径即可。

同时,我也找了第二张示例图片放在了data路径下,将"data/rice.png"更换为"data/1.webp",就可以看到演示图片中棋盘的角点检测效果。

参考文献

[1] Harris C, Stephens M. A combined corner and edge detector[C]//Alvey vision conference. 1988, 15(50): 10-5244.

​​


http://www.ppmy.cn/server/150091.html

相关文章

关于消息队列性能是否能接收 5 万个 MQ

影响性能的因素 消息队列本身的性能&#xff1a; 不同的消息队列系统&#xff08;如 RabbitMQ、Kafka、RocketMQ 等&#xff09;有不同的性能特点。例如&#xff0c;Kafka 是高吞吐量的分布式消息队列&#xff0c;能够处理大规模的消息流。它的性能在设计上可以通过分区&…

deepin下载mysql教程

官方下载 Mysql 8.2 支持 here 解压到需要的文件夹去 (建议放到 /opt/mysql/mysql8) 建立 mysql 的用户与组 &#xff08;groupadd mysql && useradd -r -g mysql mysql&#xff09; 创建软链接到系统中,后继服务与配置中会使用到 cd /usr/local &&…

12.13 深度学习-空间注意力仿射变换STN

# 就是对图像做一个仿射 变换 仿射变换的参数要去学习 直接用nn.Linear()就行 # 仿射变换的原理就是 线性变换 # 这个仿射变换要加在模型最开始的地方 import torch import torch.nn as nn import torch.nn.functional as F class STN(nn.Module): def __init__(self, c, …

【Unity高级】如何获取着色器(Shader)的关键词

在动态设置Shader时&#xff0c;会需要通过EnableKeyword, DisableKeyword来完成。但一个Shader有哪些关键词呢&#xff1f;Unity的文档中并没有列出来&#xff0c;但我们可以通过遍历Shader的KeywordSpace来查看。 1. 代码如下 using UnityEngine;public class KeywordExamp…

中信建投张青减持交易课堂:金融智慧与公益的交响曲

在当今瞬息万变的金融市场中&#xff0c;中信建投张青减持交易课堂如同一股清流&#xff0c;不仅以其专业的金融培训体系引领行业风向&#xff0c;更将公益精神深深融入教育之中&#xff0c;谱写了一曲金融智慧与公益情怀的华美乐章。张青&#xff0c;这位在金融界享有盛誉的投…

游戏引擎学习第44天

仓库: https://gitee.com/mrxiao_com/2d_game 向量数学的重要性 矢量数学非常重要&#xff0c;因为 它在某种程度上类似于将C和C视为高于汇编语言的语言&#xff0c;从而使得我们能够以略高的层次思考问题&#xff0c;同时保留大部分性能好处和直接访问的类型。这种思维方式就…

设置了pointer-events: none;后,鼠标悬停不会触发el-tooltip的显示逻辑

问题&#xff1a; el-tooltip是一个提供文字提示的组件&#xff0c;通常依赖于鼠标悬停&#xff08;hover&#xff09;事件来显示提示信息。当内层元素设置了pointer-events: none;后&#xff0c;鼠标悬停事件会穿过这个内层元素&#xff0c;不会触发el-tooltip的显示逻辑。如…

如果你想在 Android 上使用 Python 开发应用

如果你想在 Android 上使用 Python 开发应用&#xff0c;以下是一些常见的工具和框架&#xff0c;可以帮助你将 Python 与 Android 结合起来实现应用开发&#xff1a; 1. Kivy Kivy 是一个开源 Python 库&#xff0c;支持快速开发跨平台应用&#xff0c;包括 Android。Kivy 适…