欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV Canny边缘检测

程序员文章站 2024-01-28 16:49:22
...

目标

在本章中,我们将了解

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

理论

Canny边缘检测是一种流行的边缘检测算法。它是由约翰·F·坎尼于1986年开发的。这是一个多阶段的算法。

降噪

由于边缘检测对图像中的噪声很敏感,第一步是用5x5高斯滤波器去除图像中的噪声。 

图像强度梯度的求取

然后在水平方向和垂直方向用Sobel核对平滑后的图像进行滤波,得到水平方向的一阶导数(OpenCV Canny边缘检测)和垂直方向(OpenCV Canny边缘检测)从这两幅图像中,我们可以找到每个像素的边缘梯度和方向如下:

OpenCV Canny边缘检测

梯度方向总是垂直于边缘。它是圆形的四个角之一,代表垂直,水平和两个对角线方向。

非极大抑制

在获得梯度幅值和方向后,对图像进行全面扫描,以消除可能不构成边缘的任何不需要的像素。为此,在每个像素上,检查像素是否是其邻域内沿梯度方向的局部最大值。检查下面的图像:

OpenCV Canny边缘检测

A点在边缘(垂直方向)。梯度方向是正常的边缘。点B和C呈梯度方向。因此,用点B和点C检查点A,看看它是否形成局部最大值。如果是,则考虑到下一阶段,否则就会被抑制(将为零)。

简而言之,你得到的结果是一幅带有“薄边”的二值图像。

迟滞阈值

这个阶段决定了哪些是边缘,哪些是真正的边,哪些不是边。为此,我们需要两个阈值,MinVal和MaxVal。任何强度梯度大于MaxVal肯定是边,而小于MinVal肯定是非边缘的,所以被丢弃了。处于这两个阈值之间的人根据其连通性分为边缘或非边缘。如果它们连接到“确定边缘”像素,则它们被视为边缘的一部分。否则,它们也会被丢弃。见下图:

OpenCV Canny边缘检测

边缘A在MaxVal,因此被认为是“确定边缘”。虽然边缘C在MaxVal下面,但是它与边A相连,因此也被认为是有效边,我们得到了这条全曲线。但是边缘B,虽然它在上面MinVal并且与边缘C的区域相同,它没有连接到任何“确定边”,因此被丢弃。所以我们必须相应地选择MinVal和MaxVal,得到正确的结果。

这一阶段也消除了小像素噪声的假设,边缘是长线。所以我们最终得到的是图像中的强边。

OpenCV中的Canny边缘检测

OpenCV将上述所有功能都放在一个函数中,cv2.Canny()。我们会看看如何使用它。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的MinVal和MaxVal。第三个参数是aperture_size。它是用于查找图像梯度的Sobel核的大小。默认情况下是3。最后一个参数是L2gradient ,它指定了求梯度幅值的公式。如果是True,它使用上面提到的更精确的方程,否则它使用这个函数:OpenCV Canny边缘检测。默认情况下,它是False。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('messi5.jpg',0)
edges = cv2.Canny(img,100,200)

plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show()

见以下结果:

OpenCV Canny边缘检测

相关标签: OpenCV