1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > python-opencv之图像梯度Sobel Scharr Laplacian算子边缘检测

python-opencv之图像梯度Sobel Scharr Laplacian算子边缘检测

时间:2021-05-15 08:19:56

相关推荐

python-opencv之图像梯度Sobel Scharr Laplacian算子边缘检测

Sobel算子

是离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度,梯度越大越有可能是边缘。

Soble算子的功能集合了高斯平滑和微分求导,又被称为一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到的是图像在X方法与Y方向梯度图像。

缺点:比较敏感,容易受影响,要通过高斯模糊(平滑)来降噪。Sobel算子并没有将图像的主体与背景严格地区分开来,换言之就是Sobel算子没有基于图像灰度进行处理,由于Sobel算子没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。

梯度计算:(在两个方向求导,假设被作用图像为 I)

水平变化: 将 I 与一个奇数大小的内核 Gx进行卷积。比如,当内核大小为3时, Gx的计算结果为:

垂直变化: 将:math:I 与一个奇数大小的内核 Gy进行卷积。比如,当内核大小为3时, Gy的计算结果为:

在图像的每一点,结合以上两个结果求出近似梯度:

有时也用下面更简单公式代替,计算速度快:(最终图像梯度)。

函数原型

cv2.Sobel( src, ddepth, dx, dy[,ksize[, scale[, delta[, borderType]]]] )

 dst 代表目标图像。

 src 代表原始图像。

 ddepth 代表输出图像的深度。

 dx 代表 x 方向上的求导阶数。

 dy 代表 y 方向上的求导阶数。

 ksize 代表 Sobel 核的大小。该值为-1 时,则会使用 Scharr 算子进行运算。

 scale 代表计算导数值时所采用的缩放因子,默认情况下该值是 1,是没有缩放的。

 delta 代表加在目标图像 dst 上的值,该值是可选的,默认为 0。

 borderType 代表边界样式。

在实际操作中,计算梯度值可能会出现负数。通常处理的图像

是 8 位图类型,如果结果也是该类型,那么所有负数会自动截断为 0,发生信息丢失。所以,为了避免信息丢失,我们在计算时使用更高的数据类型 cv2.CV_64F,再通过取绝对值将其映射为 cv2.CV_8U(8 位图)类型。

故此我们还需要调用convertScaleAbs()函数计算绝对值,并将图像转换为8位图进行显示。其算法原型如下:

convertScaleAbs(src[, dst[, alpha[, beta]]])

 dst 代表处理结果。

 src 代表原始图像。

 alpha 代表调节系数,该值是可选值,默认为 1。

 beta 代表调节亮度值,该值是默认值,默认为 0。

代码

import cv2import matplotlib.pyplot as pltimport numpy as npimg =cv2.imread("./cycle.png",cv2.IMREAD_COLOR)kernel = np.ones((5,5),np.uint8)opening = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)cv2.imshow("opening",opening)sobelx = cv2.Sobel(opening,cv2.CV_64F,1,0,ksize=3)sobelx = cv2.convertScaleAbs(sobelx)cv2.imshow("sobelx",sobelx)sobely = cv2.Sobel(opening,cv2.CV_64F,0,1,ksize=3)sobely = cv2.convertScaleAbs(sobely)cv2.imshow("sobely",sobely)sobel = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)cv2.imshow("sobel",sobel)cv2.waitKey(0)cv2.destroyAllWindows()

结果显示

Scharr算子

为了能够有效的提取出较弱的边缘,需要将像素值间的差距增大,因此引入Scharr算子。Scharr算子是对Sobel算子差异性的增强,因此两者之间的在检测图像边缘的原理和使用方式上相同。Scharr算子的边缘检测滤波的尺寸为3×3,因此也有称其为Scharr滤波器。可以通过将滤波器中的权重系数放大来增大像素值间的差异,Scharr算子就是采用的这种思想,其在X方向和Y方向的边缘检测算子如中所示

函数原型

Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]])

参数就不一一解释了,类似于sobel

Laplacian算子

laplacian 算子,从图中可以看出当前点的位置与周围4个点位置之差, 即周围四个点之和 - 4*当前位置像素点,这种算法容易受到噪声点的干扰,不存在x和y轴的计算过程

函数原型

cv2.Laplacian(src, ddepth)

代码实例

import cv2import matplotlib.pyplot as pltimport numpy as npimg =cv2.imread("./lena.jpg",cv2.IMREAD_GRAYSCALE)sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)sobelx = cv2.convertScaleAbs(sobelx)sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)sobely = cv2.convertScaleAbs(sobely)sobel = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)scharrx = cv2.convertScaleAbs(scharrx)scharry = cv2.Scharr(img,cv2.CV_64F,0,1)scharry = cv2.convertScaleAbs(scharry)scharr = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)laplacian = cv2.Laplacian(img,cv2.CV_64F)laplacian = cv2.convertScaleAbs(laplacian)res = np.hstack((img,sobel,scharr,laplacian))cv2.imshow("res",res)cv2.waitKey(0)cv2.destroyAllWindows()

结果展示

三种算子的结果与原图对比

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。