opencv|【OpenCV + Python】Canny 边缘检测

对平滑后的图像使用Sobel 算子计算水平方向和竖直方向的一阶导数(图像梯度)(Gx 和Gy)。根据得到的这两幅梯度图(Gx 和Gy)找到边界的梯度和方向,梯度的方向一般总是与边界垂直。梯度方向被归为四类:垂直,水平,和两个对角线。
opencv|【OpenCV + Python】Canny 边缘检测
文章图片

在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的。
现在要确定那些边界才是真正的边界。这时我们需要设置两个阈值:minVal 和maxVal。当图像的灰度梯度高于maxVal 时被认为是真的边界,那些低于minVal 的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃。
【opencv|【OpenCV + Python】Canny 边缘检测】opencv|【OpenCV + Python】Canny 边缘检测
文章图片

A 高于阈值maxVal 所以是真正的边界点,C 虽然低于maxVal 但高于minVal 并且与A 相连,所以也被认为是真正的边界点。而B 就会被抛弃,因为他不仅低于maxVal 而且不与真正的边界点相连。所以选择合适的maxVal和minVal 对于能否得到好的结果非常重要。在这一步一些小的噪声点也会被除去,因为我们假设边界都是一些长的线段。
在OpenCV 中只需要一个函数:cv2.Canny(),就可以完成以上几步。让我们看如何使用这个函数。这个函数的第一个参数是输入图像。第二和第三个分别是minVal 和maxVal。第三个参数设置用来计算图像梯度的Sobel卷积核的大小,默认值为3。 最后一个参数是L2gradient,它可以用来设定求梯度大小的方程。如果设为True(L2gradient参数表示L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加),就会使用我们上面提到过的方程,否则使用方程:
opencv|【OpenCV + Python】Canny 边缘检测
文章图片

代替,默认值为False。

import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('1.png',0) edges = cv2.Canny(img,100,200,3) 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|【OpenCV + Python】Canny 边缘检测
文章图片

#Canny边缘提取 import cv2 as cv def edge_demo(image): blurred = cv.GaussianBlur(image, (3, 3), 0) gray = cv.cvtColor(blurred, cv.COLOR_RGB2GRAY) # xgrad = cv.Sobel(gray, cv.CV_16SC1, 1, 0) #x方向梯度 # ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1) #y方向梯度 # edge_output = cv.Canny(xgrad, ygrad, 50, 150) edge_output = cv.Canny(gray, 50, 150) cv.imshow("Canny Edge", edge_output) dst = cv.bitwise_and(image, image, mask= edge_output) cv.imshow("Color Edge", dst) src = https://www.it610.com/article/cv.imread('E:/imageload/liu.jpg') cv.namedWindow('input_image', cv.WINDOW_NORMAL) #设置为WINDOW_NORMAL可以任意缩放 cv.imshow('input_image', src) edge_demo(src) cv.waitKey(0) cv.destroyAllWindows()

opencv|【OpenCV + Python】Canny 边缘检测
文章图片

应用场景,使用步骤:
①高斯模糊 - GaussianBlur
②灰度转换 - cvtColor
③计算梯度 – Sobel/Scharr
④非最大信号抑制
⑤高低阈值输出二值图像

    推荐阅读