当某人对通过轮廓识别物体感兴趣时,边缘检测是一种必不可少的图像分析技术,并且也被认为是从图像中恢复信息的必不可少的步骤。
例如,可以使用边缘检测来提取重要特征,例如直线和曲线,然后通常由更高级别的计算机视觉或图像处理算法使用。 一个好的边缘检测算法将突出显示图像中主要边缘的位置,同时忽略由噪声引起的任何虚假边缘。
但是,边缘到底是什么? 边缘是可用于估计和分析图像中对象结构的图像特征。 它们表示图像强度(即像素值)中发生的重大局部变化。 边缘通常出现在图像中两个不同区域之间的边界上。
在本教程中,我将描述Canny边缘检测器算法,以及如何在Python中实现它。
坎尼边缘检测器
Canny边缘检测器算法以其发明者John F. 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
库。
使用scikit-image
Canny Edge检测器
如果您的计算机上尚未安装scikit-image
,请按照安装scikit映像页面上显示的说明继续进行安装 。
当我使用Ubuntu
计算机时,我只需要在终端中运行以下命令即可启动并运行该库:
sudo apt-get install python-skimage
scikit-image
库具有canny()
函数,我们可以使用该函数在图像上应用Canny边缘检测器。 请注意,该功能是feature
模块的一部分。
在继续之前,让我们使用一个玩具图像进行试验。 您可以使用任何图像。 我将使用下面显示的boat.png图像(单击链接以下载图像):
事不宜迟,让我们看看如何使用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()
上应用canny()
函数(除了图像,我没有传递任何自定义参数,而是将其保留为函数的默认值)。 最后,我们显示显示检测到的边缘的结果。 上面脚本的结果如下:
您可以使用参数来获得如何检测边缘的不同结果。 但是对于那些检测到的边缘,结果看起来不错,不是吗?
使用OpenCV
Canny Edge检测器
在本节中,我们将看到如何使用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库介绍 。
上面脚本的结果如下:
结论
在本教程中,我们了解了Canny边缘检测器,并了解了scikit-image
和OpenCV
库如何使我们能够通过几行代码轻松实现该检测器。
翻译自: https://code.tutsplus.com/tutorials/canny-edge-detector-using-python--cms-30095