当前位置: 首页 > news >正文

【计算机视觉】边缘检测

图像的边缘简单来说就是图像中灰度不连续的地方。
在这里插入图片描述

1.图像梯度

图像梯度是指图像像素灰度值在某个方向上的变化;图像梯度是图像的一阶导数,实际计算时可以使用差分来近似。

1.1 什么是图像梯度?

图像梯度是一种数学工具,用于描述图像中像素值变化的速度和方向。换句话说,它反映了图像亮度值在空间上的变化率,因此是边缘检测特征提取图像分析中常用的重要概念。

1.1.1 图像梯度的定义

给定一幅二维灰度图像 I ( x , y ) I(x, y) I(x,y),它的梯度是一个向量,定义如下:

∇ I = ( ∂ I ∂ x , ∂ I ∂ y ) \nabla I = \left( \frac{\partial I}{\partial x}, \frac{\partial I}{\partial y} \right) I=(xI,yI)

  • ( ∂ I ∂ x ) ( \frac{\partial I}{\partial x} ) (xI):图像在 x x x-方向上的变化率(水平梯度)。
  • ( ∂ I ∂ y ) ( \frac{\partial I}{\partial y} ) (yI):图像在 y y y-方向上的变化率(垂直梯度)。

梯度的大小方向定义如下:

  • 梯度大小(Gradient Magnitude):
    ∣ ∇ I ∣ = ( ∂ I ∂ x ) 2 + ( ∂ I ∂ y ) 2 |\nabla I| = \sqrt{\left( \frac{\partial I}{\partial x} \right)^2 + \left( \frac{\partial I}{\partial y} \right)^2} ∣∇I=(xI)2+(yI)2
  • 梯度方向(Gradient Direction):
    θ = arctan ⁡ ( ∂ I ∂ y ∂ I ∂ x ) \theta = \arctan\left(\frac{\frac{\partial I}{\partial y}}{\frac{\partial I}{\partial x}}\right) θ=arctan(xIyI)
1.1.2 如何计算图像梯度

在离散图像中,梯度的计算通常使用滤波器(卷积核)近似求导数。以下是常见方法:

1. 基本差分(Finite Difference)

利用相邻像素值的差分近似求导数:

  • ( ∂ I ∂ x ≈ I ( x + 1 , y ) − I ( x , y ) ) ( \frac{\partial I}{\partial x} \approx I(x+1, y) - I(x, y) ) (xII(x+1,y)I(x,y))
  • ( ∂ I ∂ y ≈ I ( x , y + 1 ) − I ( x , y ) ) ( \frac{\partial I}{\partial y} \approx I(x, y+1) - I(x, y) ) (yII(x,y+1)I(x,y))
2. Sobel算子

Sobel算子是一种常用的离散梯度滤波器,使用以下卷积核:

  • 水平梯度核( G x G_x Gx):
    [ − 1 0 1 − 2 0 2 − 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix} 121000121
  • 垂直梯度核( G y G_y Gy):
    [ − 1 − 2 − 1 0 0 0 1 2 1 ] \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix} 101202101

使用 Sobel 算子计算出的梯度既平滑了噪声,又能准确提取边缘。

3. Scharr算子

Scharr算子是 Sobel 算子的改进版,能更好地处理图像细节。它的权值分布更均匀,适合高精度梯度计算。

4. 拉普拉斯算子

拉普拉斯算子计算的是二阶导数,用于检测图像的变化区域,而不是简单的一阶变化。

1.2 梯度的计算示例
import cv2 as cv
import numpy as np# 加载图像
img = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)# 计算水平和垂直梯度
grad_x = cv.Sobel(img, cv.CV_64F, 1, 0, ksize=3)  # 水平梯度
grad_y = cv.Sobel(img, cv.CV_64F, 0, 1, ksize=3)  # 垂直梯度# 计算梯度大小
magnitude = cv.magnitude(grad_x, grad_y)# 显示结果
cv.imshow('Original', img)
cv.imshow('Gradient X', cv.convertScaleAbs(grad_x))
cv.imshow('Gradient Y', cv.convertScaleAbs(grad_y))
cv.imshow('Gradient Magnitude', cv.convertScaleAbs(magnitude))
cv.waitKey(0)
cv.destroyAllWindows()
1.3 梯度的应用
  1. 边缘检测:
    • 梯度强度大的地方往往是图像边缘,结合阈值可以提取轮廓(如 Canny 边缘检测)。
  2. 特征提取:
    • 梯度方向是许多特征描述符(如 SIFT、HOG)的基础。
  3. 图像增强:
    • 利用梯度信息可以增强图像的边缘或细节。
  4. 运动检测:
    • 梯度变化在时间序列中的对比可以用来检测运动或变化区域。

2.Canny边缘检测

Canny边缘检测是一种经典的多步骤边缘检测算法,由 John F. Canny 在 1986 年提出。它以鲁棒性、高准确性和抗噪性著称,广泛用于图像处理和计算机视觉任务中。

2.1 算法步骤

Canny 边缘检测分为以下几个步骤:

1. 噪声抑制(平滑处理)
  • 目标:减少噪声对边缘检测的影响。

  • 方法:对图像进行高斯模糊。
    高斯模糊会平滑图像中的细节和噪声,同时保留大的结构边缘。

    公式(高斯滤波器):
    G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x, y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} G(x,y)=2πσ21e2σ2x2+y2
    其中, σ \sigma σ 决定平滑程度(模糊核的标准差)。

2. 计算图像梯度
  • 目标:找出图像中的边缘,即像素值变化剧烈的区域。

  • 方法:使用 Sobel 算子计算水平梯度 ( G x G_x Gx) 和垂直梯度 ( G y G_y Gy),然后计算梯度的大小和方向。

    梯度大小(强度)计算公式:
    ∣ G ∣ = G x 2 + G y 2 |G| = \sqrt{G_x^2 + G_y^2} G=Gx2+Gy2

    梯度方向计算公式:
    θ = arctan ⁡ ( G y G x ) \theta = \arctan\left(\frac{G_y}{G_x}\right) θ=arctan(GxGy)

    • 梯度强度大的地方可能是边缘。
    • 梯度方向用于后续的非极大值抑制。
3. 非极大值抑制(Non-Maximum Suppression)
  • 目标:精确定位边缘,去除非边缘的噪声响应。

  • 方法

    • 在梯度方向上检查当前像素值是否为局部极大值。
    • 如果不是局部极大值,则将该像素设为 0(非边缘)。

    操作:

    • 将梯度方向分为四个主方向(0°、45°、90°、135°)。
    • 比较当前像素与梯度方向上相邻两个像素的大小。
4. 双阈值边缘检测
  • 目标:区分强边缘、弱边缘和非边缘。
  • 方法
    • 设置两个阈值:高阈值 ( T h i g h T_{high} Thigh) 和低阈值 ( T l o w T_{low} Tlow)。
    • 对梯度强度进行分类:
      • 强边缘:梯度强度 > T h i g h > T_{high} >Thigh
      • 弱边缘 T l o w < 梯度强度 ≤ T h i g h T_{low} < \text{梯度强度} \leq T_{high} Tlow<梯度强度Thigh
      • 非边缘:梯度强度 l e q T l o w leq T_{low} leqTlow
5. 边缘连接(Hysteresis Thresholding)
  • 目标:确定最终的边缘。
  • 方法
    • 强边缘直接保留。
    • 弱边缘若与强边缘相连,则保留为边缘;否则丢弃。
2.2 Canny 边缘检测的代码实现
import cv2 as cv
import numpy as np# 加载图像(灰度模式)
img = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)# Canny 边缘检测
edges = cv.Canny(img, threshold1=50, threshold2=150)# 显示结果
cv.imshow('Original Image', img)
cv.imshow('Canny Edges', edges)
cv.waitKey(0)
cv.destroyAllWindows()
2.3 Canny 函数参数详解
cv.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)
  1. image:输入图像,必须为灰度图像。
  2. threshold1:低阈值,用于区分弱边缘和非边缘。
  3. threshold2:高阈值,用于区分强边缘和弱边缘。
  4. apertureSize:Sobel 算子的核大小(默认为 3)。常用值:3、5、7。
  5. L2gradient:布尔值,是否使用更精确的梯度计算(默认为 False)。
    • 如果为 True,则使用 L2 范数( G x 2 + G y 2 \sqrt{G_x^2 + G_y^2} Gx2+Gy2 )。
    • 如果为 False,则使用 L1 范数( ∣ G x ∣ + ∣ G y ∣ |G_x| + |G_y| Gx+Gy)。
2.4 Canny 边缘检测的优点
  1. 鲁棒性:可以很好地抵抗噪声,适用于复杂场景。
  2. 多步骤处理:包括平滑、梯度计算和非极大值抑制,结果更加精确。
  3. 边缘连接:通过双阈值和滞后连接有效去除了孤立的边缘点。
2.5 Canny 边缘检测的缺点
  1. 参数敏感:双阈值的选择对结果影响很大,需要手动调整。
  2. 计算成本高:多步骤处理增加了算法复杂度,不适合实时性要求高的应用。
2.6 应用场景
  1. 边缘检测:
    • 图像分割前的边缘提取。
  2. 特征提取:
    • 用于形状识别或物体检测。
  3. 运动检测:
    • 对帧差图像进行边缘检测,以识别移动物体的轮廓。

相关文章:

【计算机视觉】边缘检测

图像的边缘简单来说就是图像中灰度不连续的地方。 1.图像梯度 图像梯度是指图像像素灰度值在某个方向上的变化&#xff1b;图像梯度是图像的一阶导数&#xff0c;实际计算时可以使用差分来近似。 1.1 什么是图像梯度&#xff1f; 图像梯度是一种数学工具&#xff0c;用于描…...

林曦词典|无聊

“林曦词典”是在水墨画家林曦的课堂与访谈里&#xff0c;频频邂逅的话语&#xff0c;总能生发出无尽的思考。那些悠然轻快的、微妙纷繁的&#xff0c;亦或耳熟能详的词&#xff0c;经由林曦老师的独到解析&#xff0c;意蕴无穷&#xff0c;让人受益。于是&#xff0c;我们将诸…...

LabVIEW光栅衍射虚拟仿真系统

随着现代教育技术的快速发展&#xff0c;虚拟仿真实验平台逐渐成为物理实验教学的重要辅助工具。基于LabVIEW的平面透射光栅虚拟仿真系统帮助学生更好地理解和分析光栅衍射现象&#xff0c;提高教学质量和学生的学习兴趣。 项目背景 在波动光学的教学中&#xff0c;光栅衍射实…...

【NumPy进阶】:内存视图、性能优化与高级线性代数

目录 1. 深入理解 NumPy 的内存视图与拷贝1.1 内存视图&#xff08;View&#xff09;1.1.1 创建视图1.1.2 视图的特点 1.2 数组拷贝&#xff08;Copy&#xff09;1.2.1 创建拷贝1.2.2 拷贝的特点 1.3 视图与拷贝的选择 2. NumPy 的优化与性能提升技巧2.1 向量化操作示例&#x…...

从YOLOv5到训练实战:易用性和扩展性的加强

文章目录 前言一、模型介绍二、YOLOv5网络结构1.Input&#xff08;输入端&#xff09;&#xff1a;智能预处理与优化策略2.Backbone&#xff08;骨干网络&#xff09;&#xff1a;高效特征提取3.NECK&#xff08;颈部&#xff09;&#xff1a;特征增强与多尺度融合4.Prediction…...

Prim 算法在不同权重范围内的性能分析及其实现

Prim 算法在不同权重范围内的性能分析及其实现 1. 边权重取值在 1 到 |V| 范围内伪代码C 代码实现2. 边权重取值在 1 到常数 W 之间结论Prim 算法是一种用于求解加权无向图的最小生成树(MST)的经典算法。它通过贪心策略逐步扩展生成树,确保每次选择的边都是当前生成树到未加…...

canal安装使用

简介 canal [kənl]&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费 工作原理 canal 模拟 MySQL slave 的交互协议&#xff0c;伪装自己为 MySQL slave &#xff0c;向 MySQL master 发送 dump 协议…...

python爬虫常用数据保存模板(Excel、CSV、mysql)——scrapy中常用数据提取方法(CSS、XPATH、正则)(23)

文章目录 1、常用数据保存模板2.1 保存为Excel格式2.2 保存为CSV格式2.3 保存至mysql数据库2、scrapy中常用数据提取方法2.1 XPath选择器2.2 CSS选择器2.3 正则表达式1、常用数据保存模板 2.1 保存为Excel格式 # 1、导入模块 from openpyxl import workbook# 2、创建一个exce…...

You need to call SQLitePCL.raw.SetProvider()

在.NET环境中使用Entity Framework Core&#xff08;EF Core&#xff09;连接SQLite数据库时&#xff0c;报错。 使用框架 .NET8 错误信息&#xff1a; Exception: You need to call SQLitePCL.raw.SetProvider(). If you are using a bundle package, this is done by calling…...

IoTDB AINode 报错,call inference 301: Error ocurred while executing inference

问题及现象 使用时序数据库 IoTDB 的 AINode 的 call inference 语句后报错&#xff1a; Msg: org.apache.iotdb.jdbc.IoTDBSOLException&#xff1a;301: Error ocurred while executing inference:[tuple object has no attribute inference]解决方法 可以替换 venv 里面的…...

LLM之RAG实战(五十)| FastAPI:构建基于LLM的WEB接口界面

FastAPI是WEB UI接口&#xff0c;随着LLM的蓬勃发展&#xff0c;FastAPI的生态也迎来了新的机遇。本文将围绕FastAPI、OpenAI的API以及FastCRUD&#xff0c;来创建一个个性化的电子邮件写作助手&#xff0c;以展示如何结合这些技术来构建强大的应用程序。 下面我们开始分步骤操…...

项目-移动端适配的几种方案

目录 一、rem方案二、vw适配方案 一、rem方案 以vue2项目为例 下载安装包&#xff1a;npm install amfe-flexible --save在main.js中引入&#xff1a;import ‘amfe-flexible’下载安装包&#xff1a;npm install postcss-pxtorem --save项目下新建postcss.config.js文件&…...

HCIA-Access V2.5_2_2网络通信基础_TCP/IP协议栈报文封装

TCP/IP协议栈的封装过程 用户从应用层发出数据先会交给传输层&#xff0c;传输层会添加TCP或者UDP头部&#xff0c;然后交给网络层&#xff0c;网络层会添加IP头部&#xff0c;然后交给数据链路层&#xff0c;数据链路层会添加以太网头部和以太网尾部&#xff0c;最后变成01这样…...

LSTM详解

1. LSTM设计 LSTM(长短期记忆网络)详解 长短期记忆网络(LSTM, Long Short-Term Memory) 是一种特殊的循环神经网络(RNN),特别适合处理和预测序列数据中的长时间依赖关系。LSTM 通过引入“门机制”(如输入门、遗忘门、输出门)来解决标准 RNN 在长时间序列任务中梯度消…...

从零开始搭建Android开发环境:简单易懂的完整教程

前言&#xff1a; 作为安卓开发的入门&#xff0c;搭建开发环境是每个开发者都必须迈出的第一步。虽然这一步看似简单&#xff0c;但如果没有正确的配置&#xff0c;可能会遇到各种问题。本篇文章将为大家详细介绍如何从零开始搭建Android开发环境&#xff0c;确保你能够顺利开…...

大模型运用-Prompt Engineering(提示工程)

什么是提示工程 提示工程 提示工程也叫指令工程&#xff0c;涉及到如何设计、优化和管理这些Prompt&#xff0c;以确保AI模型能够准确、高效地执行用户的指令&#xff0c;如&#xff1a;讲个笑话、java写个排序算法等 使用目的 1.获得具体问题的具体结果。&#xff08;如&…...

CMake简单使用(二)

目录 五、scope 作用域5.1 作用域的类型5.1.1 全局作用域5.1.2 目录作用域5.1.3 函数作用域 六、宏6.1 基本语法6.2 演示代码 七、CMake构建项目7.1 全局变量7.2 写入源码路径7.3 调用子目录cmake脚本7.4 CMakeLists 嵌套(最常用) 八、CMake 与库8.1 CMake生成动静态库8.1.1 动…...

攻防世界安卓刷题笔记(新手模式)1-4

1.基础android 进入后是这样的页面。查看源代码看看。首先要注意这个软件并没有加壳&#xff0c;所以我们可以直接着手分析。搜索错误提示“Failed”定位到关键代码&#xff0c;看样子就是检验输入的内容 注意到这里有一行关键代码&#xff0c;cond_39对应的正是failed那个地方…...

发现一个对话框中的按钮,全部失效,点击都没有任何反应,已经解决

前端问题&#xff0c;技术vue2&#xff0c;ts。 发现一个对话框中的按钮&#xff0c;全部失效&#xff0c;点击都没有任何反应。 因为我只在template标签中加入下面这个代码&#xff0c;并没有注册。 只要有一个子组件没有注册&#xff0c;就会影响所有的按钮&#xff0c;使当前…...

MyBatisPlus实现多表查询

在MyBatisPlus中实现多表查询&#xff0c;主要有以下几种方法&#xff1a; 使用注解进行多表查询&#xff1a; 你可以在Mapper接口中使用Select注解来编写SQL查询语句&#xff0c;实现多表查询。例如&#xff0c;如果你想根据用户ID查询用户信息和对应的区域名称&#xff0c;可…...

17步拆解!一张图看懂AIAgent全流程,轻松掌握大模型应用开发核心!

本文通过一张图详细拆解了AIAgent从用户提问到结果返回的17步全流程&#xff0c;深入探讨了提示词、Agent、大模型、MCP和工具等关键要素在智能体架构中的作用。文章揭示了它们如何共同构建从自然语言意图到智能决策、工具执行再到结果反馈的完整闭环&#xff0c;为开发者提供了…...

AI情感操控案:多模态交互诱发群体性癔症

从代码逻辑到情感逻辑的测试盲区在软件测试领域&#xff0c;我们习惯于与确定的输入、输出和状态机打交道。我们构建严密的测试用例&#xff0c;验证功能边界&#xff0c;追求接近100%的代码覆盖率。然而&#xff0c;当被测对象从传统的软件系统&#xff0c;转变为能够理解、响…...

基于Vue的社区老年人健康管理与服务预约网站[vue]-计算机毕业设计源码+LW文档

摘要&#xff1a;随着人口老龄化的加剧&#xff0c;社区老年人健康管理与服务预约的需求日益增长。为了提高社区老年人健康管理的效率和服务质量&#xff0c;本文设计并实现了一个基于Vue的社区老年人健康管理与服务预约网站。文章详细阐述了系统的开发背景、相关技术、需求分析…...

解锁Windows 10的Android生态:3大革新功能让跨设备体验无缝融合

解锁Windows 10的Android生态&#xff1a;3大革新功能让跨设备体验无缝融合 【免费下载链接】WSA-Windows-10 This is a backport of Windows Subsystem for Android to Windows 10. 项目地址: https://gitcode.com/gh_mirrors/ws/WSA-Windows-10 副标题&#xff1a;WS…...

基于51单片机的太阳能追光系统设计与仿真:包含光敏控制、电机调速及两种模式的太阳跟踪系统

基于51单片机的太阳能追光系统设计&#xff0c;太阳跟踪系统设计&#xff0c;光敏控制系统protues仿真设计。 有仿真&#xff0c;程序&#xff0c;AD图&#xff0c;原文&#xff0c;相关资料。 本系统可以通过光敏电阻调节电机转速&#xff0c;有手动模式和我自动模式。 适用于…...

实例】四相机测量项目源码使用海康SDK及C#+halcon实现的通俗易懂教程:连接相机、模板匹...

四相机测量项目源码&#xff0c;海康相机SDK&#xff0c;C#halcon&#xff0c;写得比较通俗易懂&#xff0c;四相机四种测量模式&#xff0c;某工厂产线曾使用的项目。 主要功能有连接海康相机采图&#xff0c;模板匹配&#xff0c;圆形拟合&#xff0c;直线拟合&#xff0c;像…...

实用算法:布隆过滤器原理与手写实现,彻底解决缓存穿透

实用算法&#xff1a;布隆过滤器原理与手写实现&#xff0c;彻底解决缓存穿透 前言&#xff1a;在高并发系统中&#xff0c;缓存是提升性能的核心手段&#xff0c;但缓存穿透问题常常成为系统的“隐形杀手”——恶意请求不存在的Key&#xff0c;绕过缓存直接冲击数据库&#xf…...

Qwen2.5-7B-Instruct法律科技:合同审查要点+修改建议+合规风险等级评估

Qwen2.5-7B-Instruct法律科技&#xff1a;合同审查要点修改建议合规风险等级评估 1. 项目简介&#xff1a;智能法律助手的技术底座 Qwen2.5-7B-Instruct是阿里通义千问推出的旗舰级大模型&#xff0c;专门针对专业级文本交互场景深度优化。相比轻量版的1.5B和3B版本&#xff…...

仅限TOP20量化机构内部流通的C++内存池测试矩阵(含FPGA协处理器适配层验证项),现在限时解密!

第一章&#xff1a;金融级C内存池测试的范式演进与行业背景在高频交易、实时风控与低延迟结算等金融核心系统中&#xff0c;内存分配性能直接决定毫秒级响应能力的上限。传统 malloc/free 在高并发小对象场景下易引发锁争用、碎片化加剧与缓存行失效&#xff0c;迫使头部券商与…...

网络和并发 第五节:Python中的多线程

一、线程的相关概念 在Python中,想要实现多任务除了使用进程,还可以使用线程来完成,线程是实现多任务的另外一种方式。 1、什么是线程 线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度 ,也就是说线程是cpu调度的基本单位,每个进…...