• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用 Python 的 Canny 边缘检测器

当有人对通过轮廓识别对象感兴趣时,边缘检测是一种必不可少的图像分析技术,它也被认为是从图像中恢复信息的重要步骤。 

例如,边缘检测可以提取直线和曲线等重要特征,这些特征通常会被更高级别的计算机视觉或图像处理算法使用。一个好的边缘检测算法会突出图像中主要边缘的位置,同时忽略由噪声引起的任何错误边缘。 

但是到底什么是边缘?边缘是图像特征,可用于估计和分析图像中对象的结构。它们代表图像强度(即像素值)的显着局部变化。边缘通常出现在图像中两个不同区域之间的边界上。

在本教程中,我将描述 Canny 边缘检测算法并向您展示我们如何在 python 中实现它。

Canny 边缘检测器

Canny 边缘检测算法以其发明者John F. Canny的名字命名,他于 1986 年发明了该算法。Canny 边缘检测器通常将灰度图像作为输入,并生成显示强度不连续性位置的图像作为输出(即边缘) .

我不想在这里进行数学运算,但我将从高层次的角度描述 Canny 边缘检测器算法幕后发生的事情。

Canny 边缘检测器做的第一件事是它使用高斯卷积来平滑输入图像并去除噪声。然后将一阶导数算子应用于平滑图像以突出显示具有高一阶空间导数的图像区域。

该算法然后通过计算 x 导数和 y 导数来找到梯度大小和方向,特别是因为知道梯度的方向使我们能够找到边缘的方向。

该算法然后执行所谓的非最大抑制,它沿着从边缘上升的脊的顶部进行跟踪,并将那些不在脊顶部的像素设置为零,最终在结果中产生一条细线。 

换句话说,我们检查在上一步中计算的梯度是否被认为是位于梯度正负方向上的相邻点中的最大值。如果梯度最大,则认为它是边缘的一部分,反之亦然。

上面的跟踪过程由两个阈值控制,t1和t2,这样t1>t2,称为 滞后阈值。 跟踪从山脊上t1高于t2. 

所以,基本上,这里发生的是我们选择所有高于阈值上限的边缘点,t1然后调查这些点是否有被认为低于阈值上限t1 和高于阈值下限的邻居t2。在这种情况下,这样的邻居将成为边缘的一部分。

因此,用于平滑输入图像的高斯核的宽度以及跟踪器使用的t1(上)和t2(下)阈值是确定 canny 边缘检测器效果的参数。

Python 实现

在本节中,我将介绍两种实现 Canny 边缘检测器的方法。一种方式使用 scikit-image库,另一种方式使用OpenCV库。

Canny 边缘检测器使用scikit-image

如果您尚未在计算机上安装,请按照安装 scikit-image页面scikit-image上显示的说明继续安装它。

由于我使用的是 Ubuntu 机器,我只需在终端中运行以下命令即可启动并运行该库:

sudo apt-get install python-skimage

该scikit-image库有一个canny()函数,我们可以使用它在我们的图像上应用 Canny 边缘检测器。请注意,该函数是feature模块的一部分。

在继续之前,让我们使用玩具图像进行试验。不过,您可以使用任何图像。我将使用如下所示的boat.png图像:

使用 Python 的 Canny 边缘检测器  第1张

事不宜迟,让我们看看如何使用 Canny 边缘检测器检测上图(即船)中的边缘。请记住,我们的图像需要是灰度的。由于我们的图像已经是灰度的,所以此时我们不需要做任何事情,例如将图像从彩色转换为灰度。Canny 边缘检测器的脚本如下所示:

from skimage import io
from skimage import feature
im = io.imread('boat.png')
edges = feature.canny(im)
io.imshow(edges)
io.show()

如您所见,我们首先读取图像boat.png. 之后,我们canny()在图像上应用该函数(我没有传递任何自定义参数,除了我们的图像,并将其保留为函数的默认值)。最后,我们显示显示检测到的边缘的结果。上述脚本的结果如下所示:

使用 Python 的 Canny 边缘检测器  第2张

您可以使用这些参数来获得有关如何检测边缘的不同结果。但是对于那些检测到的边缘,结果看起来不错,不是吗?

Canny 边缘检测器使用OpenCV

在本节中,我们将了解如何OpenCV在我们的船图像上应用 Canny 边缘检测器。如果您还没有安装 OpenCV,请继续安装它。您可以查看以下有关如何OpenCV在计算机上安装的文章。我为不同的操作系统包含了不同的文章:

  • Ubuntu 16.04:如何安装 OpenCV

  • 在 Windows 中安装 OpenCV-Python

  • macOS 上安装 OpenCV 3

与scikit-image库一样,OpenCV也有一个函数调用canny(),用于在图像上应用 Canny 边缘检测算法。以下脚本显示了我们如何使用它OpenCV来查找图像中的边缘:

import cv2
import matplotlib.pyplot as plt
im = cv2.imread('boat.png')
edges = cv2.Canny(im,25,255,L2gradient=False)
plt.imshow(edges,cmap='gray')
plt.show()

请注意,我已将以下内容作为参数传递给Canny()函数:

  • im: 图片名称

  • lower threshold: 25

  • upper threshold: 255

  • L2gradient=False:这意味着使用了L1 范数。如果设置为True,将使用L2 范数。

该matplotlib库随后被用于绘制结果。要了解有关此库的更多信息,请查看我的教程:介绍 Python 的 Matplotlib 库。 

上述脚本的结果如下:

使用 Python 的 Canny 边缘检测器  第3张

结论

在本教程中,我们了解了 Canny 边缘检测器,并了解了scikit-image和OpenCV库如何使我们能够使用几行代码轻松实现此检测器。

文章目录
  • Canny 边缘检测器
  • Python 实现
    • Canny 边缘检测器使用scikit-image
    • Canny 边缘检测器使用OpenCV
  • 结论
  • 发表评论