►前言
上篇介绍使用OpenCV Python findContours() 函数用于在二值化影像中寻找连通的白色区域,并返回一系列点的集合来表示找到的轮廓。本篇将介绍基于计算影像的梯度,通过在影像中找到梯度值的变化来识别边缘,边缘检测通常用于预处理步骤,以帮助后续的物体侦测、分割或其他影像处理任务。透过程式码的说明,让各位了解OpenCV Python于图像处理上的基本操作。
►边缘检测定义
边缘检测是指在数字图像中寻找并识别物体边界的过程。在影像处理中,边缘通常表示著图像中不同区域之间的剧烈变化或不连续性,这些变化可能由物体的几何结构、亮度、颜色或纹理等特征引起。边缘检测的目标是找到这些变化的位置,以便进一步的分析和处理,例如物体侦测、图像分割、特征提取等。常见的边缘检测算法有Canny边缘检测、Sobel算子、Laplacian算子等。
►Canny边缘检测
OpenCV提供Canny ()函数用于在灰度影像中寻找轮廓。由于边缘侦测容易受到影像中杂讯的影响,因此用 5x5 高斯滤波器去除影像中的杂讯。然后使用 Sobel 在水平和垂直方向上对平滑后的图像进行滤波,获得水平方向上的一阶导数(??
)和垂直方向(??),如下所示:

获得梯度大小和方向后,对影像进行全面扫描,以去除可能不构成边缘的任何不必要的像素,因此在每个像素处,检查像素是否是其邻域中梯度方向的局部最大值。

最后透过两个阈值minVal 和 maxVal,进行边缘判断,梯度大于 maxVal 的任何边缘是图像边缘,而低于 minVal 的边缘不是图像边缘。



►Sobel算子
Sobel 算子是一种离散的微分算子,结合了高斯平滑和微分求导运算。利用局部差分寻找边缘,计算梯度的近似值。





►Laplacian算子
Laplacian算子采用二阶导数来侦测边缘,因为二阶导数在边缘位置为零,透过二阶倒数运算便可以得知边缘位置。




►小结
透过以上讲解,搭配程式码进行范例讲解,相信各位对于图像上的边缘检测能有更深刻的理解,期待下一篇博文吧!
►Q&A
问题一:如何在OpenCV中进行边缘侦测?
在 OpenCV 中,可以使用 cv2.Canny() 函数进行边缘侦测。此函数需要输入灰阶影像,并且通常需要调整两个阈值参数来控制边缘侦测的灵敏度。
问题二:如何选择适当的阈值参数进行边缘检测?
选择适当的阈值参数取决于影像的特性以及应用需求。一般来说,可以透过试验不同的参数值并观察结果来进行调整。较低的阈值会导致更多的边缘被侦测出来,而较高的阈值则会限制侦测到的边缘数量。
问题三:如何对边缘侦测结果进行后处理?
边缘检测常常会产生一些断断续续的边缘,因此可以对检测结果进行后处理来提高品质。常见的后处理步骤包括二值化、非最大值抑制和边缘连接等。
问题四:如何在不同的影像类型上进行边缘检测?
OpenCV 的边缘侦测函数通常接受灰阶影像作为输入,因此对于彩色影像,需要先将其转换为灰阶影像。可以使用 cv2.cvtColor() 函数将彩色影像转换为灰阶影像。
问题五:如何显示边缘检测结果?
显示边缘侦测结果与显示原始影像类似。可以使用 cv2.imshow() 函数显示影像,然后透过 cv2.waitKey() 等待按键输入,并最后使用 cv2.destroyAllWindows() 关闭所有视窗。