热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python实现Canny边缘检测算法

图像中的边缘信息主要集中在高频部分,因此图像锐化或边缘检测实质上是进行高频滤波。微分运算能够增强信号的高频成分,从而在空间域中通过计算微分实现图像锐化。本文将详细介绍如何使用Python实现Canny边缘检测算法。
图像中的边缘信息主要集中在高频部分,因此图像锐化或边缘检测实质上是进行高频滤波。微分运算能够增强信号的高频成分,从而在空间域中通过计算微分实现图像锐化。对于数字图像的离散信号,微分运算转换为计算差分或梯度。图像处理中有多种边缘检测算子,如普通一阶差分、Roberts 算子(交叉差分)、Sobel 算子等,这些算子主要用于寻找梯度强度。拉普拉斯算子(二阶差分)则用于过零点检测。

Canny 边缘检测算子是一种多阶段的边缘检测算法,由 John F. Canny 在 1986 年提出,并提出了边缘检测的三个关键准则:
1. **低错误率**:算法应尽可能准确地检测到图像中的边缘,减少漏检和误检。
2. **最优定位**:检测到的边缘点应尽可能精确地位于实际边缘的中心。
3. **唯一性**:图像中的每个边缘应仅被标记一次,且不应因噪声而产生虚假边缘。

自 Canny 算法提出以来,它一直被视为标准的边缘检测算法,并且在此基础上发展出多种改进算法。即使在今天,Canny 算法及其变体仍然是非常优秀的边缘检测方法,除非特定条件非常适合其他算子,否则很难找到显著优于 Canny 的边缘检测算子。

### Canny 算法实现步骤
1. **高斯模糊**
这一步类似于 LoG 算子(Laplacian of Gaussian)中的高斯模糊,主要目的是去除噪声。噪声集中在高频信号中,容易被误认为边缘。通过高斯模糊去除噪声,可以减少伪边缘的检测。然而,图像边缘信息也是高频信号,因此高斯模糊的半径选择非常重要,过大的半径可能会导致弱边缘丢失。

2. **计算梯度幅值和方向**
图像的边缘可以指向不同的方向,经典 Canny 算法使用四个梯度算子分别计算水平、垂直和对角线方向的梯度。但通常情况下,使用如 Roberts、Prewitt 和 Sobel 等边缘差分算子计算水平和垂直方向的差分 Gx 和 Gy,进而计算梯度模和方向。

梯度角度 θ 范围从 -π 到 π,将其近似到四个方向:水平(0°)、垂直(90°)和两个对角线方向(45°、135°)。可以将每个区域的梯度角映射到这四个方向之一。

本文选择 Sobel 算子计算梯度。Sobel 算子简单易用,广泛应用于边缘检测,但其检测的边缘通常较粗且亮度较高。

3. **非最大值抑制**
非最大值抑制是一种边缘细化方法,用于将梯度边缘细化为单像素宽度。通常,梯度边缘会有多像素宽,特别是使用 Sobel 算子时。非最大值抑制通过保留局部最大梯度值并抑制其他梯度值来实现这一点。

具体算法如下:
- 比较当前点的梯度强度与其正负梯度方向上的点的梯度强度。
- 如果当前点的梯度强度大于其同方向上的其他点,则保留其值;否则,抑制该点,即将其值设为 0。

例如,如果当前点的方向为 90°,则需与垂直方向上的上下两个像素进行比较。

4. **双阈值检测**
传统的边缘检测算法通常使用一个阈值来滤除噪声或颜色变化引起的小梯度值,而保留大梯度值。Canny 算法则使用双阈值,即一个高阈值和一个低阈值。如果边缘像素的梯度值大于高阈值,则认为是强边缘点;如果梯度值介于高低阈值之间,则标记为弱边缘点;小于低阈值的点则被抑制。

5. **滞后边界跟踪**
强边缘点被认为是真正的边缘,而弱边缘点可能由噪声或颜色变化引起。为了获得精确的结果,应去除由噪声引起的弱边缘点。通常认为,真实的弱边缘点与强边缘点相连,而由噪声引起的弱边缘点则不相连。滞后边界跟踪算法通过检查弱边缘点的 8 邻域像素,如果其中存在强边缘点,则保留该弱边缘点。

该算法通过深度优先搜索(DFS)或广度优先搜索(BFS)实现,本文采用的是 DFS 方法。

### 实验结果
下面是对 Lena 图像应用 Canny 边缘检测的实验结果,高斯半径为 2,高阈值为 100,低阈值为 50。

- **Canny 检测梯度模图**
- **Canny 检测梯度二值图**

作为对比,下面是使用一阶差分和 Sobel 算子对原图计算的结果,阈值为 100。由于一阶差分的梯度值较小,因此对其进行了放大处理,使其与 Sobel 算子的梯度值保持一致。

- **一阶差分梯度模图**
- **一阶差分梯度二值图**
- **Sobel 梯度模图**
- **Sobel 梯度二值图**

可以看出,Canny 边缘检测的效果非常显著,不仅大大减少了噪声引起的伪边缘,而且边缘更加细化,便于后续处理。对于对比度较低的图像,通过调整参数,Canny 算法也能取得良好的效果。
推荐阅读
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 深入解析JVM垃圾收集器
    本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版,详细探讨了JVM中不同类型的垃圾收集器及其工作原理。通过介绍各种垃圾收集器的特性和应用场景,帮助读者更好地理解和优化JVM内存管理。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文详细介绍了如何在BackTrack 5中配置和启动SSH服务,确保其正常运行,并通过Windows系统成功连接。涵盖了必要的密钥生成步骤及常见问题解决方法。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 本文将介绍由密歇根大学Charles Severance教授主讲的顶级Python入门系列课程,该课程广受好评,被誉为Python学习的最佳选择。通过生动有趣的教学方式,帮助初学者轻松掌握编程基础。 ... [详细]
author-avatar
ssl87
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有