OpenCV 4.11.0
开源计算机视觉
加载中…
搜索中…
无匹配项
Canny 边缘检测

目标

  • Canny 边缘检测的概念
  • 用于此的 OpenCV 函数:cv.Canny()

理论

Canny 边缘检测是一种流行的边缘检测算法。它由 John F. Canny 于 1986 年开发。它是一个多阶段算法,我们将逐步介绍每个阶段。

  1. 降噪

    由于边缘检测易受图像噪声的影响,第一步是使用 5x5 高斯滤波器去除图像噪声。我们已经在前面的章节中看到过这一点。

  2. 查找图像的强度梯度

    然后使用 Sobel 核对平滑后的图像进行水平和垂直方向的滤波,以获得水平方向(\(G_x\))和垂直方向(\(G_y\))的一阶导数。从这两幅图像中,我们可以找到每个像素的边缘梯度和方向,如下所示

    \[ 边缘梯度 \; (G) = \sqrt{G_x^2 + G_y^2} \\ 角 \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg) \]

    梯度方向始终垂直于边缘。它四舍五入到四个角度之一,分别表示垂直、水平和两个对角方向。

  3. 非极大值抑制

    获得梯度幅度和方向后,对图像进行全扫描以去除任何可能不构成边缘的无关像素。为此,在每个像素处,检查该像素在其梯度方向上的邻域中是否为局部最大值。请查看下面的图像

图像

点 A 位于边缘(垂直方向)。梯度方向垂直于边缘。点 B 和 C 位于梯度方向上。因此,检查点 A 与点 B 和 C 是否形成局部最大值。如果是,则将其考虑用于下一阶段,否则将其抑制(设置为零)。

简而言之,您得到的结果是一幅具有“细边缘”的二值图像。

  1. 滞后阈值

    此阶段决定哪些边缘是真正的边缘,哪些不是。为此,我们需要两个阈值,minVal 和 maxVal。任何强度梯度大于 maxVal 的边缘肯定都是边缘,而低于 minVal 的边缘肯定是非边缘,因此被丢弃。介于这两个阈值之间的那些根据其连通性被分类为边缘或非边缘。如果它们连接到“确定边缘”像素,则它们被认为是边缘的一部分。否则,它们也会被丢弃。请参见下图

图像

边缘 A 高于 maxVal,因此被认为是“确定边缘”。虽然边缘 C 低于 maxVal,但它与边缘 A 相连,因此也被认为是有效的边缘,我们得到了完整的曲线。但是边缘 B,虽然它高于 minVal 并且与边缘 C 位于同一区域,但它没有连接到任何“确定边缘”,因此被丢弃。因此,必须相应地选择 minVal 和 maxVal 才能获得正确的结果。

此阶段还基于边缘是长线的假设去除了小的像素噪声。

因此,我们最终得到的是图像中的强边缘。

OpenCV 中的 Canny 边缘检测

我们使用函数:cv.Canny(image, edges, threshold1, threshold2, apertureSize = 3, L2gradient = false)

参数
图像8 位输入图像。
edges输出边缘图;单通道 8 位图像,大小与 image 相同。
threshold1滞后过程的第一个阈值。
threshold2滞后过程的第二个阈值。
apertureSizeSobel 算子的孔径大小。
L2gradient指定查找梯度幅度的方程。如果为 True,则使用上面提到的更精确的方程,否则使用此函数:\(边缘梯度 \; (G) = |G_x| + |G_y|\)。

试一试