sobel算子 scharr算子 laplacian算子

sobel算子

参数ksize:sobel核的大小,为-1时会使用scharr算子运算
直接将参数ddepth的值设置为-1,在计算时得到的结果可能是错误的。 在实际操作中,计算梯度值可能会出现负数。如果处理的图像是8位图类型,则在ddepth的参数值为-1时,意味着指定运算结果也是8位图类型,那么所有负数会自动截断为0,发生信息丢失。为了避免信息丢失,在计算时要先使用更高的数据类型 cv2.CV_64F,再通过取绝对值将其映射为cv2.CV_8U(8位图)类型。所以,通常要将函数cv2.Sobel()内参数ddepth的值设置为“cv2.CV_64F”。

可用函数cv2.convertScaleAbs()对参数取绝对值,该函数的语法格式为: dst=cv2.convertScaleAbs(src[,alpha[,beta]]) 上式中:
● dst代表处理结果。
● src代表原始图像。
● alpha代表调节系数,该值是可选值,默认为1。
● beta代表调节亮度值,该值是默认值,默认为0。 这里,该函数的作用是将原始图像src转换为256色位图,其可以表示为: dst=saturate(src*alpha+beta)

在函数cv2.Sobel()中,参数dx表示x轴方向的求导阶数,参数dy表示y轴方向的求导阶数。参数dx和dy通常的值为0或者1,最大值为2。如果是0,代表在该方向没有求导,dx与dy不能同时为0

img = cv2.imread("p7.jpg")
dst = cv2.Sobel(img,-1,1,0)

在这里插入图片描述

img = cv2.imread("p7.jpg")
dst = cv2.Sobel(img,-1,0,1)

在这里插入图片描述
没感觉两个图片有什么差别。可能是因为ddepth参数的原因。

设置dst = cv2.Sobel(img,cv2.CV_64F,0,1) #获得垂直方向的边缘信息
在这里插入图片描述
可以看到很多的水平线了。
改为:

dst = cv2.Sobel(img,cv2.CV_64F,1,0)

在这里插入图片描述
从程序可以看出,将参数ddepth的值设置为“cv2.CV_64F”,参数dx和dy的值设置为“dx=0,dy=1”的情况下,使用函数 cv2.convertScaleAbs()对函数 cv2.Sobel()的计算结果取绝对值,可以获取图像在垂直方向的完整边缘信息。

在垂直和水平方向叠加边缘信息

img = cv2.imread("p7.jpg")
dst = cv2.Sobel(img,cv2.CV_64F,0,1)
dst2 = cv2.Sobel(img,cv2.CV_64F,1,0)
dst = cv2.convertScaleAbs(dst)
dst2 = cv2.convertScaleAbs(dst2)
r = cv2.addWeighted(dst,0.5,dst2,0.5,0)
cv2.imshow("i",r)

在这里插入图片描述

Sobel算子

在离散的空间上,有很多方法可以用来计算近似导数,在使用3×3的Sobel算子时,可能计算结果并不太精准。OpenCV提供了Scharr算子,该算子具有和Sobel算子同样的速度,且精度更高。可以将Scharr算子看作对Sobel算子的改进

函数cv2.Scharr()和函数cv2.Sobel()的使用方式基本一致。 首先,需要注意的是,参数ddepth的值应该设置为“cv2.CV_64F”,并对函数cv2.Scharr()的计算结果取绝对值,才能保证得到正确的处理结果。具体语句为:

 dst=Scharr(src,cv2.CV_64F,dx,dy) 
 dst=cv2.convertScaleAbs(dst) 

另外,需要注意的是,在函数cv2.Scharr()中,要求参数dx和dy满足条件: dx >=0 && dy >=0 && dx+dy==1
当函数cv2.Sobel()中ksize的参数值为-1时,就会使用Scharr算子进行运算。因此,
dst=cv2.Sobel(src,ddpeth,dx,dy,-1) 等价于
dst=cv2.Scharr(src,ddpeth,dx,dy)

二者对比

用两个算子计算一幅图水平边缘和垂直边缘的叠加信息

img = cv2.imread("p7.jpg")
dst = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
dst2 = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
dst = cv2.convertScaleAbs(dst)
dst2 = cv2.convertScaleAbs(dst2)
r1 = cv2.addWeighted(dst,0.5,dst2,0.5,0)
scharrx = cv2.Scharr(img,cv2.CV_64F,0,1)
scharry = cv2.Scharr(img,cv2.CV_64F,1,0)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)

r = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
cv2.imshow("schar",r)
cv2.imshow("sobel",r1)

在这里插入图片描述

laplacian

 式中:
  ● dst代表目标图像。 
  ● src代表原始图像。 
  ● ddepth代表目标图像的深度。 
  ● ksize代表用于计算二阶导数的核尺寸大小。该值必须是正的奇数。

```python
img = cv2.imread("p7.jpg")

lapci = cv2.Laplacian(img,cv2.CV_64F,ksize=3)
lapci = cv2.convertScaleAbs(lapci)
cv2.imshow("lap",lapci)

当未写ksize=3的效果:
在这里插入图片描述
设置ksize=3:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41358574/article/details/114198706