OpenCV 边缘检测

Ammar Ali 2024年2月15日
  1. OpenCV Canny 边缘检测
  2. OpenCV Sobel 边缘检测
OpenCV 边缘检测

边缘检测广泛用于图像处理中的背景去除、形状检测和图像结构分析。在图像处理中,图像中存在的边缘被表征为像素强度水平的突然变化。

例如,如果有一张黑色背景的猫的图片,在这张图片的边缘,会出现颜色或像素值的突然变化,比如从黑色到白色。

OpenCV 中有两种方法可以用来检测图像中存在的边缘,一种是 Canny 边缘检测器,另一种是 Sobel 边缘检测器。

本教程将讨论使用 OpenCV 中的 canny 或 Sobel 边缘检测器检测图像中的边缘。

OpenCV Canny 边缘检测

我们可以使用 OpenCV 的 Canny() 函数进行精明边缘检测。我们必须使用 GaussianBlur() 函数来平滑图像以获得更好的结果。

由于像素强度的突然变化,在边缘检测期间可以检测到一些额外的边缘,这些边缘不是我们想要检测的实际边缘的一部分。这就是为什么我们需要去除给定图像中存在的噪声。

例如,让我们使用 imread() 函数读取图像并使用 cvtColor() 函数将其转换为灰度。

之后,我们将对图像进行平滑处理,然后将其与上下阈值一起传递到 Canny() 函数中,以检测图像中存在的边缘。

请参阅下面的代码。

import cv2

img_src = cv2.imread("cat.jpg")
cv2.imshow("Original", img_src)

gray_img = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
blur_img = cv2.GaussianBlur(gray_img, (3, 3), 0)
img_edges = cv2.Canny(image=blur_img, threshold1=50, threshold2=155)

cv2.imshow("Canny Edge Detection", img_edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:

坎尼边缘检测器

Canny 边缘检测器是多级的,它通过多个步骤来找到图像中存在的边缘。第一步,该算法减少给定图像中存在的噪声。

第二步,算法求给定图像在 x 和 y 方向的一阶导数,然后利用该导数求出边缘梯度的大小和角度。

第三步,该算法通过比较局部最大像素与其邻域来去除不需要的边缘。

第四步,算法使用用户定义的两个强度级别过滤边缘。如果边缘的值在定义的强度范围之间,则将其视为有效边缘。

在上面的代码中,Canny() 函数的第一个参数 image 是给定的图像,应该是 8 位的。第二个参数 threshold1 和第三个参数 threshold2 设置阈值范围。

Canny() 函数还有两个可选参数。第一个可选参数 apertureSize 用于设置 Sobel 算子的孔径大小,默认情况下,其值设置为 3。

第二个可选参数 L2gradient 设置渐变类型。默认情况下,正常梯度设置为 false,如果我们将其设置为 true,函数将使用 L2 梯度。

如果我们在 Canny() 函数中更改阈值范围,输出将会改变,因为范围过滤了边缘。

OpenCV Sobel 边缘检测

如上所述,canny 边缘检测器是多级的。它去除噪声,找到边缘,并使用阈值范围过滤它们。

如果我们不想去除噪声或过滤边缘,我们可以使用 OpenCV 的 Sobel() 函数而不是 Canny()Sobel() 函数求图像在 x、y 或两个方向的导数,然后将图像与核卷积得到 Sobel 边缘图像。

Sobel() 函数还使用像素强度的突然变化来查找边缘。例如,让我们使用 Sobel() 函数查找上述猫图像的边缘。

请参阅下面的代码。

import cv2

img_src = cv2.imread("cat.jpg")
cv2.imshow("Original", img_src)

gray_img = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
blur_img = cv2.GaussianBlur(gray_img, (3, 3), 0)
sobel_x = cv2.Sobel(src=blur_img, ddepth=cv2.CV_64F, dx=1, dy=1, ksize=3)

cv2.imshow("Sobel Edge Detection", sobel_x)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出:

Sobel 边缘检测器

如我们所见,上图中存在很多边缘,甚至包含不需要的边缘,因为边缘没有被过滤,我们也没有去除图像中存在的噪声。Sobel() 函数的第一个参数 src 是源图像。

第二个参数 ddepth 用于设置输出图像的深度。第三个参数 dx 用于设置 x 导数的阶,第四个参数 dy 用于设置 y 导数的阶。

第四个参数 ksize 用于设置内核大小,其值应为 1、3、5 或 7。第五个参数 scale 用于设置导数的比例因子,并且默认情况下,不使用比例。

第六个参数 delta 也是可选的,用于设置添加到输出的 delta 值。第七个参数 borderType 也是可选的,用于设置像素外插的方法,默认设置边框类型为默认边框。

检查此链接以获取有关边框类型的更多详细信息。

作者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

相关文章 - OpenCV Image