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()
函数的第一个参数 src
是源图像。
第二个参数 ddepth
用于设置输出图像的深度。第三个参数 dx
用于设置 x 导数的阶,第四个参数 dy
用于设置 y 导数的阶。
第四个参数 ksize
用于设置内核大小,其值应为 1、3、5 或 7。第五个参数 scale
用于设置导数的比例因子,并且默认情况下,不使用比例。
第六个参数 delta
也是可选的,用于设置添加到输出的 delta 值。第七个参数 borderType
也是可选的,用于设置像素外插的方法,默认设置边框类型为默认边框。
检查此链接以获取有关边框类型的更多详细信息。