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

canny边缘检测

Canny边缘检测算法是一种广泛使用的边缘检测方法,由John F.Canny在1986年提出。它被认为是边缘检测的“黄金标准”,因为它在检测边缘的同时能够很好地抑制噪声,并且能够精确地定位边缘。Canny算法通过一系列步骤来实现鲁棒的边缘检测,以下是其主要步骤的详细介绍:

1.高斯滤波降噪
由于边缘检测对噪声非常敏感,因此在进行边缘检测之前,通常需要对图像进行平滑处理以去除噪声。Canny算法使用高斯滤波器对图像进行平滑处理,以减少噪声的影响。高斯滤波器是一种低通滤波器,它通过卷积操作将图像中的每个像素与其邻域内的像素进行加权平均,从而平滑图像。

2.计算梯度幅值和方向
在图像平滑后,Canny算法计算每个像素点的梯度幅值和方向。这通常通过使用Sobel算子或其他类似的梯度算子来完成。对于每个像素点,计算其在水平方向((G_x))和垂直方向((G_y))的梯度分量,然后使用以下公式计算梯度幅值和方向:

• 梯度幅值:
[
G=\sqrt{G_x2+G_y2}
]

• 梯度方向:
[
\theta=\arctan2(G_y,G_x)
]

梯度幅值表示该像素点处的边缘强度,而梯度方向表示边缘的方向。

3.非极大值抑制
非极大值抑制是一个关键步骤,用于细化边缘。它的目的是去除那些不是局部最大值的梯度值,从而只保留那些可能是边缘的像素。具体来说,对于每个像素点,检查其梯度方向上的邻域像素。如果当前像素的梯度幅值不是其邻域中的最大值,则将其梯度幅值设置为零。这一步骤可以有效地去除边缘周围的弱响应,使得边缘更加清晰。

4.双阈值检测和边缘连接
Canny算法使用两个阈值来区分强边缘和弱边缘:

• 高阈值(High Threshold):用于检测强边缘。

• 低阈值(Low Threshold):用于检测弱边缘。

具体步骤如下:

  1. 强边缘检测:首先使用高阈值检测强边缘。所有梯度幅值大于高阈值的像素被认为是强边缘。

  2. 弱边缘检测:然后使用低阈值检测弱边缘。所有梯度幅值大于低阈值但小于高阈值的像素被认为是弱边缘。

  3. 边缘连接:最后,通过检查弱边缘像素的邻域,如果弱边缘像素与强边缘像素相连,则将其保留为边缘的一部分。否则,将其舍弃。

5.最终边缘图像
经过上述步骤后,最终得到的图像只包含强边缘和通过边缘连接保留下来的弱边缘。这些边缘通常能够很好地表示图像中的物体轮廓和结构。

Canny算法的优点

  1. 低错误率:Canny算法能够很好地抑制噪声,从而减少误检测的边缘。

  2. 良好的定位:Canny算法能够精确地定位边缘,使得边缘检测结果更加准确。

  3. 最小响应:Canny算法通过非极大值抑制和双阈值检测,确保每个边缘只被检测一次,从而减少了边缘的重复检测。

Canny算法的缺点

  1. 参数选择:Canny算法需要选择高阈值和低阈值,这些参数的选择对最终的边缘检测结果有很大影响。不同的图像可能需要不同的参数设置。

  2. 计算复杂度:Canny算法涉及多个步骤,包括高斯滤波、梯度计算、非极大值抑制和双阈值检测,这使得其计算复杂度较高。

示例代码(Python+OpenCV)
以下是一个使用Python和OpenCV实现Canny边缘检测的简单示例:

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)# 高斯滤波降噪
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)# 计算梯度幅值和方向
sobel_x = cv2.Sobel(blurred_image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(blurred_image, cv2.CV_64F, 0, 1, ksize=3)
gradient_magnitude = np.sqrt(sobel_x**2 + sobel_y**2)
gradient_direction = np.arctan2(sobel_y, sobel_x)# 非极大值抑制
def non_max_suppression(grad_mag, grad_dir):height, width = grad_mag.shapesuppressed = np.zeros_like(grad_mag, dtype=np.uint8)for i in range(1, height - 1):for j in range(1, width - 1):direction = grad_dir[i, j]if ((direction >= -22.5 and direction < 22.5) or(direction >= 157.5 or direction < -157.5)):neighbors = [grad_mag[i, j-1], grad_mag[i, j+1]]elif ((direction >= 22.5 and direction < 67.5) or(direction >= -157.5 and direction < -112.5)):neighbors = [grad_mag[i-1, j+1], grad_mag[i+1, j-1]]elif ((direction >= 67.5 and direction < 112.5) or(direction >= -112.5 and direction < -67.5)):neighbors = [grad_mag[i-1, j], grad_mag[i+1, j]]else:neighbors = [grad_mag[i-1, j-1], grad_mag[i+1, j+1]]if grad_mag[i, j] >= neighbors[0] and grad_mag[i, j] >= neighbors[1]:suppressed[i, j] = grad_mag[i, j]return suppressed# 双阈值检测和边缘连接
def hysteresis_thresholding(grad_mag, low_threshold, high_threshold):strong_edges = grad_mag > high_thresholdweak_edges = (grad_mag >= low_threshold) & (grad_mag <= high_threshold)edges = strong_edges.astype(np.uint8) * 255for i in range(1, grad_mag.shape[0] - 1):for j in range(1, grad_mag.shape[1] - 1):if weak_edges[i, j]:if np.any(strong_edges[i-1:i+2, j-1:j+2]):edges[i, j] = 255return edges# 应用非极大值抑制
suppressed_edges = non_max_suppression(gradient_magnitude, gradient_direction)# 应用双阈值检测和边缘连接
low_threshold = 50
high_threshold = 150
final_edges = hysteresis_thresholding(suppressed_edges, low_threshold, high_threshold)# 显示结果
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1), plt.imshow(image, cmap='gray'), plt.title('Original Image')
plt.subplot(1, 3, 2), plt.imshow(suppressed_edges, cmap='gray'), plt.title('Non-Max Suppression')
plt.subplot(1, 3, 3), plt.imshow(final_edges, cmap='gray'), plt.title('Final Edges')
plt.show()

总结
Canny边缘检测算法通过一系列步骤(高斯滤波、梯度计算、非极大值抑制和双阈值检测)实现鲁棒的边缘检测。它能够很好地抑制噪声,精确地定位边缘,并且通过边缘连接保留弱边缘。

领域如何判定

在Canny边缘检测算法中,非极大值抑制(Non-Maximum Suppression,NMS)是一个关键步骤,用于细化边缘,保留局部最大梯度值的点,抑制非边缘的点。其目的是使边缘只有一个像素宽,从而提高边缘检测的准确性和清晰度。

非极大值抑制的具体过程

  1. 梯度方向分类:
    在Canny算法中,梯度方向被分为四个主要方向:0°(水平)、45°(对角)、90°(垂直)和135°(对角)。这种分类简化了后续的比较操作。

  2. 局部比较:
    对于每个像素点,根据其梯度方向,选择其梯度方向上的两个邻域像素进行比较。如果当前像素的梯度幅值不是其邻域中的最大值,则将该像素的梯度幅值抑制为0,即认为它不是边缘。

邻域的定义
在非极大值抑制中,“邻域”指的是当前像素点在梯度方向上的相邻像素。具体来说:

• 如果梯度方向为0°(水平),则邻域为当前像素的左右两个像素。

• 如果梯度方向为90°(垂直),则邻域为当前像素的上下两个像素。

• 如果梯度方向为45°或135°(对角),则邻域为当前像素的对角线上的两个像素。

其他角度的处理
对于其他角度(不在上述四个主要方向上),Canny算法通常会将这些角度归类到最近的主要方向上。例如,如果梯度方向为22.5°,则可以将其归类为45°方向进行处理。这样可以简化计算,并确保所有像素点都能被有效地处理。

领域评价
在非极大值抑制中,邻域的定义和选择对于算法的性能至关重要。通过选择梯度方向上的邻域像素进行比较,可以确保只有真正的边缘点被保留下来。这种方法有效地去除了冗余的边缘响应,提高了边缘检测的准确性和鲁棒性。

应用领域
Canny边缘检测算法因其高效性和准确性,在图像处理和计算机视觉领域得到了广泛应用,包括但不限于:

• 物体检测与识别:用于检测图像中的物体轮廓,辅助物体识别。

• 图像分割:通过边缘检测将图像分割成不同的区域。

• 特征提取:提取图像中的关键特征,用于后续的图像分析。

• 机器人视觉:帮助机器人进行环境感知和路径规划。

• 医学图像分析:用于提取病变区域的边缘,辅助医生进行诊断。

Canny算法在这些领域中的应用,不仅提高了图像处理的效率,还增强了边缘检测的准确性,使其成为计算机视觉领域的一个经典算法。

相关文章:

canny边缘检测

Canny边缘检测算法是一种广泛使用的边缘检测方法&#xff0c;由John F.Canny在1986年提出。它被认为是边缘检测的“黄金标准”&#xff0c;因为它在检测边缘的同时能够很好地抑制噪声&#xff0c;并且能够精确地定位边缘。Canny算法通过一系列步骤来实现鲁棒的边缘检测&#xf…...

团建 蓝桥杯省a 15

问题描述 小蓝正在和朋友们团建&#xff0c;有一个游戏项目需要两人合作&#xff0c;两个人分别拿到一棵大小为 nn 和 mm 的树&#xff0c;树上的每个结点上有一个正整数权值。 两个人需要从各自树的根结点 1 出发走向某个叶结点&#xff0c;从根到这个叶结点的路径上经过的所…...

【逻辑学导论】1.6 有效性和真实性

当一个演绎论证成功地将结论和前提必然地联系起来&#xff0c;它是有效的。有效性是针对论证的各命题之间的关系而言的。一个论证是有效的&#xff0c;当且仅当它不可能有真前提和假结论&#xff0c;当且仅当其结论是从其前提逻辑必然地推导出来的。因此&#xff0c;有效性永远…...

IDEA 中集成 Maven,配置环境、创建以及导入项目

目录 在 IntelliJ IDEA 中集成 Maven 并配置环境 1. 打开 IDEA 设置 2. 定位 Maven 配置选项 3. 配置 Maven 路径 4. 应用配置 创建 Maven 项目 1. 新建项目 2. 选择项目类型 3. 配置项目信息 4. 确认 Maven 设置 5. 完成项目创建 导入 Maven 项目 1. 打开导入窗口…...

Qt跨屏窗口的一个Bug及解决方案

如果我们希望一个窗口覆盖用户的整个桌面&#xff0c;此时就要考虑用户有多个屏幕的场景&#xff08;此窗口要横跨多个屏幕&#xff09;&#xff0c;由于每个屏幕的分辨率和缩放比例可能是不同的&#xff0c;Qt底层在为此窗口设置缩放比例&#xff08;DevicePixelRatio&#xf…...

Vue WebSocket简单应用 ws

webSocket应用 <template><div></div> </template><script> import { getToken } from "/utils/auth"; export default {data() {return {url: "",Socket: null, //socket对象lockReconnect: false, //锁定拒绝重连close: …...

快速单机部署ollama v0.5.7 +openwebui(免去网络环境干扰)

1 概述 本文介绍在一台机器上快速部署测试ollama和openwebui&#xff0c;免去国内网络环境的干扰。 2 环境 2.1 环境 版本信息如下&#xff1a; a、操作系统&#xff1a;centos 7.9 c、docker版本&#xff1a;20.10.5-3 3 部署 3.1 安装docker yum install -y yum-util…...

【华为OD-E卷 - 114 找最小数 100分(python、java、c++、js、c)】

【华为OD-E卷 - 找最小数 100分&#xff08;python、java、c、js、c&#xff09;】 题目 给一个正整数NUM1&#xff0c;计算出新正整数NUM2&#xff0c;NUM2为NUM1中移除N位数字后的结果&#xff0c;需要使得NUM2的值最小 输入描述 输入的第一行为一个字符串&#xff0c;字…...

快速搭建GPU环境 | docker、k8s中使用gpu

目录 一、裸机部署安装 GPU Driver安装 CUDA Toolkit测试 二、Docker 环境安装 nvidia-container-toolkit配置使用该 runtime 三、 k8s 环境安装 device-plugin安装 GPU 监控 一、裸机部署 裸机中要使用上 GPU 需要安装以下组件&#xff1a; GPU DriverCUDA Toolkit 二者的关…...

VSCode设置——通过ctrl+鼠标滚动改变字体大小(新版本的vs)

"editor.mouseWheelZoom": true 第一步&#xff1a; 第二步&#xff1a;...

【kafka实战】06 kafkaTemplate java代码使用示例

在 Spring Boot 中使用 KafkaTemplate 可以方便地向 Kafka 发送消息。下面为你详细介绍使用步骤和示例代码。 1. 创建 Spring Boot 项目 你可以使用 Spring Initializr&#xff08;https://start.spring.io/ &#xff09;来创建一个新的 Spring Boot 项目&#xff0c;添加以下…...

Java 23新特性

文章目录 Java 23新特性一、引言二、Markdown文档注释&#xff08;JEP 467&#xff09;示例 三、ZGC&#xff1a;默认的分代模式&#xff08;JEP 474&#xff09;1. 为什么要引入分代模式2. 使用分代模式的优势3. 如何启用分代模式 四、隐式声明的类和实例主方法&#xff08;JE…...

bat脚本实现自动化漏洞挖掘

bat脚本 BAT脚本是一种批处理文件&#xff0c;可以在Windows操作系统中自动执行一系列命令。它们可以简化许多日常任务&#xff0c;如文件操作、系统配置等。 bat脚本执行命令 echo off#下面写要执行的命令 httpx 自动存活探测 echo off httpx.exe -l url.txt -o 0.txt nuc…...

[创业之路-285]:《产品开发管理-方法.流程.工具 》-1- IPD的功能列表以及导入步骤

一、概述&#xff1a; 对于没有IPD&#xff08;集成产品开发&#xff09;流程的公司来说&#xff0c;导入IPD需要循序渐进、有序进行&#xff0c;而不是一步到位。这是因为IPD不仅仅是一种新的产品开发流程&#xff0c;它还涉及到公司文化、组织结构、团队协作方式以及思维方式…...

Redis命令:列表模糊删除详解

前言 在Redis中&#xff0c;列表&#xff08;List&#xff09;是一种非常常用的数据结构&#xff0c;允许存储多个有序的元素。然而&#xff0c;在实际应用中&#xff0c;可能会遇到需要删除列表中符合某种模式的元素的需求。本文将详细介绍如何在Redis中实现列表的模糊删除。…...

Day36-【13003】短文,数组的行主序方式,矩阵的压缩存储,对称、三角、稀疏矩阵和三元组线性表,广义表求长度、深度、表头、表尾等

文章目录 本次课程内容第四章 数组、广义表和串第一节 数组及广义表数组的基本操作数组的顺序存储方式-借用矩阵行列式概念二维数组C语言对应的函数-通常行主序方式 矩阵的压缩存储对称矩阵和三角矩阵压缩存储后&#xff0c;采用不同的映射函数稀疏矩阵-可以构成三元组线性表三…...

大数据sql查询速度慢有哪些原因

1.索引问题 可能缺少索引&#xff0c;也有可能是索引不生效 2.连接数配置&#xff1a;连接数过少/连接池比较小 连接数过 3.sql本身有问题&#xff0c;响应比较慢&#xff0c;比如多表 4.数据量比较大 -这种最好采用分表设计 或分批查询 5.缓存池大小 可能是缓存问题&#xff…...

文件 I/O 和序列化

文件I/O C#提供了多种方式来读写文件&#xff0c;主要通过System.IO命名空间中的类来实现&#xff0c;下方会列一些常用的类型&#xff1a; StreamReader/StreamWriter&#xff1a;用于以字符为单位读取或写入文本文件。 BinaryReader/BinaryWriter&#xff1a;用于以二进制格…...

机器学习中的关键概念:通过SKlearn的MNIST实验深入理解

欢迎来到我的主页&#xff1a;【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 sklearn相关介绍 Scikit-learn 是一个广泛使用的开源机器学习库&#xff0c;提供了简单而高效的数据挖掘和数据分析工具。它建立在 NumPy、SciPy 和 matplotlib 等科学计算库之上&#xff0c;支持…...

HELLOCTF反序列化靶场全解

level 2 <?php/* --- HelloCTF - 反序列化靶场 关卡 2 : 类值的传递 --- HINT&#xff1a;尝试将flag传递出来~# -*- coding: utf-8 -*- # Author: 探姬 # Date: 2024-07-01 20:30 # Repo: github.com/ProbiusOfficial/PHPSerialize-labs # email: adminhello-ctf.com…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...