在本教程中,我们将一起学习如何在 OpenCV 中使用基于深度学习的边缘检测技术。相比经典的 Canny 边缘检测器,这种方法更加精确。边缘检测在许多计算机视觉应用中都非常重要,例如视觉显著性检测、目标检测、目标跟踪与运动分析、运动推断结构(Structure from Motion)、3D 重建、自动驾驶、图像到文本分析等。下面,我们将从基础概念入手,一步步带你掌握这项进阶技术。
01 什么是边缘检测?
边缘检测是计算机视觉中一个非常经典的问题。它的核心任务是检测图像中的边缘,从而确定目标的边界,进而分离出我们感兴趣的目标。最流行的边缘检测技术之一是Canny 边缘检测,它已经成为大多数计算机视觉研究人员和实践者的首选方法。我们首先快速回顾一下 Canny 边缘检测的基本原理。
02 Canny 边缘检测算法
1983 年,John Canny 在麻省理工学院发明了 Canny 边缘检测。它将边缘检测视为一个信号处理问题。其核心思想是:如果你观察图像中每个像素的强度变化,在边缘处,变化会非常剧烈。
在下图中,强度变化只发生在边界上。因此,你可以通过观察像素强度的变化轻松识别边缘。

再看这张图片:强度不是恒定不变的,但强度的变化率在边缘处最高(复习微积分:变化率可以用一阶导数(梯度)来计算)。

Canny 边缘检测器通过以下 4 个步骤来识别边缘:
- 去噪:因为该方法依赖强度的突然变化,如果图像包含大量随机噪声,噪声也会被误认为边缘。所以,使用 5×5 的高斯滤波器平滑图像是一个非常好的主意。
- 梯度计算:下一步,计算图像中每个像素的强度梯度(强度变化率)。同时也要计算梯度的方向。

梯度方向垂直于边缘,并被映射到四个方向之一(水平、垂直和两个对角线方向)。
- 非极大值抑制:现在,我们需要删除不是边缘的像素(设置其值为 0)。你可能会想:只需选取梯度值最高的像素即可。但在真实图像中,梯度不会仅仅在一个像素处达到峰值,而是在临近边缘的像素处都非常高。因此,我们在梯度方向上取 3×3 邻域内的局部最大值。

- 迟滞阈值化:最后,我们需要设定一个梯度阈值,低于该阈值的所有像素都将被抑制(设置为 0)。Canny 采用了迟滞阈值法,它使用两个阈值代替一个阈值:
- 高阈值:选择一个非常高的值,任何梯度值高于此阈值的像素都肯定是边缘。
- 低阈值:选择一个非常低的值,任何梯度值低于此阈值的像素绝对不是边缘。

迟滞阈值化示意图
03 Canny 边缘检测的问题
Canny 边缘检测器只关注局部变化,没有语义(对图像内容的理解)信息,因此精度有限(在很多情况下确实如此)。

上图中,Canny 边缘检测器失败的原因是缺乏对图像上下文的语义理解。
语义理解对于边缘检测至关重要,这就是为什么基于机器学习或深度学习的检测器能比 Canny 产生更好结果的原因。
