Canny 算法

边缘:我的理解是在图像处理的过程中,针对我们图像处理的过程中,梯度变化以较大的地方能够让我们能够快速辨识,针对一个人脸,脸上有一些平滑的地方(没错我针对美颜的),与头发的接壤处,会让我们清楚的意识到这个人脸的大小形状等特征。通过线条我们能够很清晰的辨认一个人的特征,因此,图像边缘是图像处理之中很简单的任务之一。

Canny 边缘检测算法是一种广泛使用的边缘检测技术,由 John F. Canny 在 1986 年提出。它被认为是最优的边缘检测算法之一,因其在检测边缘时具有较好的准确性和低噪声敏感性。Canny 算法的主要目标是识别图像中的边缘,并提供精确的边缘定位。

Canny 算法的步骤

Canny 边缘检测算法是一种多阶段的边缘检测方法,其数学原理主要包括以下几个步骤:

1. 高斯平滑

在进行边缘检测之前,首先需要对图像进行平滑处理,以减少噪声的影响。Canny 算法使用高斯滤波器来实现这一点。高斯滤波器的数学表达式为:

OpenCV 消除边缘噪音_OpenCV 消除边缘噪音

其中,OpenCV 消除边缘噪音_计算机视觉_02 是高斯分布的标准差,OpenCV 消除边缘噪音_opencv_03

2. 计算梯度

接下来,使用 Sobel 算子或其他梯度算子计算图像中每个像素的梯度强度和方向。Sobel 算子通常有两个方向的卷积核:

  • 水平方向(OpenCV 消除边缘噪音_opencv_04):
    OpenCV 消除边缘噪音_OpenCV 消除边缘噪音_05
  • 垂直方向(OpenCV 消除边缘噪音_opencv_06):
    OpenCV 消除边缘噪音_opencv_07

通过卷积操作,计算每个像素的梯度强度 OpenCV 消除边缘噪音_opencv_08 和方向 OpenCV 消除边缘噪音_计算机视觉_09

OpenCV 消除边缘噪音_算法_10

OpenCV 消除边缘噪音_opencv_11

3. 非极大值抑制

在计算出梯度强度和方向后,Canny 算法会进行非极大值抑制,以细化边缘。对于每个像素,算法会检查其梯度强度是否为局部最大值。具体步骤如下:

  • 根据梯度方向,将像素分为四个方向(OpenCV 消除边缘噪音_计算机视觉_12OpenCV 消除边缘噪音_OpenCV 消除边缘噪音_13OpenCV 消除边缘噪音_opencv_14OpenCV 消除边缘噪音_边缘检测_15)。
  • 对于每个像素,检查其在梯度方向上的前后两个像素的强度值。
  • 如果当前像素的强度值不是局部最大值,则将其强度设为零。

4. 双阈值处理

Canny 算法使用双阈值处理来确定强边缘和弱边缘。设定两个阈值(高阈值和低阈值):

  • 强边缘:梯度强度高于高阈值的像素。
  • 弱边缘:梯度强度介于低阈值和高阈值之间的像素。
  • 非边缘:梯度强度低于低阈值的像素。

5. 边缘连接

最后,Canny 算法通过连接强边缘和弱边缘来形成最终的边缘图。只有与强边缘相连的弱边缘才会被保留,其他的弱边缘将被抑制。这一过程确保了边缘的连续性。

Canny 边缘检测算法的数学原理结合了高斯平滑、梯度计算、非极大值抑制、双阈值处理和边缘连接等多个步骤。通过这些步骤,Canny 算法能够有效地检测图像中的边缘,并提供较高的准确性和鲁棒性。

Canny 算法的优点

  • 高精度:Canny 算法能够准确地检测到边缘,并且对噪声具有较强的鲁棒性。
  • 多级阈值:通过双阈值处理,可以有效地分离强边缘和弱边缘,增强边缘的连通性。
  • 细化边缘:非极大值抑制步骤使得边缘更加细化,减少了边缘的宽度。

Canny 算法的缺点

  • 计算复杂度:相较于其他简单的边缘检测算法(如 Roberts、Sobel),Canny 算法的计算复杂度较高,处理速度较慢。
  • 参数选择:高斯滤波器的标准差和双阈值的选择对结果有较大影响,可能需要根据具体应用进行调整。

应用场景

Canny 边缘检测算法广泛应用于计算机视觉和图像处理领域,包括但不限于:

  • 物体检测与识别
  • 图像分割
  • 特征提取
  • 机器人视觉
  • 医学图像分析

总之,Canny 边缘检测算法因其高效性和准确性,成为了边缘检测领域的经典算法之一。

Canny算法步骤

  • 去燥(常用高斯滤波)

任何边缘检测算法都不可能在未经处理的原始数据上很好地工作,使用高斯滤波可以去除常见的噪声。

OpenCV 消除边缘噪音_边缘检测_16

・计算梯度大小和方向
梯度的大小和方向往往可以反应图像灰度值的变化和方向, 可以通过点乘一个sobel或其它算子得到不同方向的梯度值。
常见的梯度算子:canny算子,sobel算子,拉普拉斯算子
・沿着梯度方向进行非极大值抑制

  • 双边阈值处理
  • 低于低阈值的舍弃, 高于阈值的确定为边缘, 在中间的如果与边缘相连接保留,否则舍去。

cv2.Canny 是 OpenCV 中用于执行 Canny 边缘检测的函数。该函数的主要作用是检测图像中的边缘,并返回一个二值图像,其中边缘像素为白色(255),非边缘像素为黑色(0)。

函数原型

edges = cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)

参数说明

  1. image (numpy.ndarray):
  • 描述:输入图像,通常是一个灰度图像。Canny 边缘检测算法通常在灰度图像上运行,因此如果输入是彩色图像,需要先将其转换为灰度图像。
  1. threshold1 (int):
  • 描述:低阈值,用于边缘连接的第一阈值。该值用于确定强边缘和弱边缘的分界。梯度强度低于此值的像素被认为是非边缘。
  1. threshold2 (int):
  • 描述:高阈值,用于边缘连接的第二阈值。该值用于确定强边缘的分界。梯度强度高于此值的像素被认为是强边缘。
  1. apertureSize (int, 可选):
  • 描述:Sobel 算子的大小,默认为 3。该参数决定了用于计算图像梯度的 Sobel 算子的大小。可以设置为 1、3、5 或 7。较大的值会导致更平滑的边缘,但可能会丢失一些细节。
  1. L2gradient (bool, 可选):
  • 描述:是否使用更精确的 L2 范数来计算梯度。默认为 False,表示使用 L1 范数。如果设置为 True,则使用 L2 范数,这样可以获得更精确的边缘检测结果。

返回值

  • edges (numpy.ndarray):
  • 返回一个二值图像,其中边缘像素为白色(255),非边缘像素为黑色(0)。

cv2.Canny 函数是实现 Canny 边缘检测的主要工具,通过合理设置阈值和其他参数,可以有效地检测图像中的边缘特征。选择合适的阈值和参数对于获得最佳的边缘检测效果至关重要。

import cv2

img = cv2.imread("./images/25.jpg",cv2.IMREAD_COLOR)

cv2.imshow("canny",img)

img = cv2.convertScaleAbs(img,alpha=6,beta=0)

cv2.imshow("abs",img)
# 高斯滤波
img = cv2.GaussianBlur(img,(5,5),1)

canny = cv2.Canny(img,100,150)

canny = cv2.resize(canny,(500,500))
cv2.imshow("Canny",canny)
cv2.waitKey(0)

OpenCV 消除边缘噪音_计算机视觉_17