作者:ssl87 | 来源:互联网 | 2024-12-02 16:15
图像中的边缘信息主要集中在高频部分,因此图像锐化或边缘检测实质上是进行高频滤波。微分运算能够增强信号的高频成分,从而在空间域中通过计算微分实现图像锐化。本文将详细介绍如何使用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 算法也能取得良好的效果。