边缘检测原理

边缘检测(Edge Detection)是图像处理和计算机视觉中的基本问题,其目的在于标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。边缘的表现形式如下图所示:

边缘检测 python 边缘检测原理_边缘检测 python


图像边缘检测大幅度地减少了数据量,并且剔除了可看作不相关的信息,保留了图像重要的结构属性。边缘检测的方法可大致划分为两类:

1)基于搜索:通过寻找图像一阶导数中的最大值和最小值来检测边界,通常是将边界定位在梯度最大的方向,代表算法是Sobel算子和Scharr算子。

2)基于零穿越:通过寻找图像二阶导数零穿越来寻找边界,通常是Laplacian过零点或者非线性差分表示的过零点,代表算法是Laplacian算子。

Canny边缘检测算法

Canny边缘检测算法是一种非常流行的边缘检测算法,是JohnF.Canny于1986年提出的,被认为是最优的边缘检测算法。它可分为4个步骤:去除噪声、计算图像梯度、非极大值抑制和滞后阈值。

去除噪声

边缘检测极易受到噪声影响,因此需要使用高斯滤波器去除噪声。

计算图像梯度幅值与方向

在数学中,梯度的本意是一个向量,表示函数在某点的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向变化最快,变化率最大。

图像中用梯度表示灰度值的变化程度与方向,而边缘就是指灰度强度变化最强的位置。梯度方向与边缘方向呈垂直关系。

此处采用Sobel滤波器计算梯度的大小和方向。Sobel算子GX是水平方向的一阶导数,用于检测Y轴方向的边缘,而GY则是竖直方向的一阶导数,用于检测X轴方向的边缘。

边缘检测 python 边缘检测原理_图像处理_02

非极大值抑制

非极大值抑制(Non-MaximumSuppression,NMS),即保留局部最大值,
抑制非局部最大值的所有值。简单而言,就是对图像的所有像素点进行检测,如果某点的梯度强度大于其梯度方向的正负方向的像素点,则该点保留;否则,该点被抑制。
Canny边缘检测算法是沿着梯度方向对幅值进行非极大值抑制的,而非边缘方向。

滞后阈值

为了确定真正的边界,需要设定两个阈值“minVal”和“maxVal”。当图像某点的灰度梯度大于阈值“maxVal”,该点被视为真的边界点;当某点的灰度梯度小于阈值“minVal”,则该点不看作边界点;当某点的灰度梯度介于两个阈值之间,根据该点是否与真的边界点相连来进行判断,相连则将该点也看作边界点,否则将其抛弃。

代码

import cv2
import numpy as np
import matplotlib.pyplot as plt

#图像读取
img = cv2.imread("test.jpg")

#Canny边缘检测
lowThreshold = 1 #最小阈值
max_lowThershold = 80 #最大阈值
canny = cv2.Canny(img, lowThreshold, max_lowThreshold)

#图像展示
plt.figure(figsize = (8, 5), dpi = 100)
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(121), plt.imshow(img, camp=plt.cm.grap). plt.title("Original")
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(canny, cmap = plt.cm.gray), plt.title("Edge Detection")
plt.xticks([]), plt.yticks([])
plt.show()