scharr算子介绍
在离散的空间上,有很多方法可以用来计算近似导数,在使用3×3的Sobel算子时,可能计算结果并不太精准。OpenCV提供了Scharr算子,该算子具有和Sobel算子同样的速 度,且精度更高。可以将Scharr算子看作对Sobel算子的改进,其核通常为:
scharr算子函数语法
Opencv提供了函数cv2.Scharr()来计算Scharr算子,其语法格式如下
dst=cv2.Scharr(src,ddepth,dx,dy[,scale[,delta[,borderType]]])
式中:
● dst代表输出图像。
● src代表原始图像。必须是8位或浮点数单通道图像。
● ddepth代表输出图像深度。例如-1表示与原图像保持一致。
● dx代表x方向上的导数阶数。
● dy代表y方向上的导数阶数。
● scale代表计算导数值时的缩放因子,该项是可选项,默认值是1,表示没有缩放。
● delta代表加到目标图像上的亮度值,该项是可选项,默认值为0。
● borderType代表边界样式。像素外插法类型,默认是cv2.BORDER_DEFAULT。
注意:
函数cv2.Scharr()和函数cv2.Sobel()的使用方式基本一致。 首先,需要注意的是,参数ddepth的值应该设置为“cv2.CV_64F”,并对函数 cv2.Scharr()的计算结果取绝对值,才能保证得到正确的处理结果。
另外,需要注意的是,在函数cv2.Scharr()中,要求参数dx和dy满足条件:
dx >=0 && dy >=0 && dx+dy==1
因此,参数dx和参数dy的组合形式有:
● 计算x方向边缘(梯度):dx=1,dy=0。
● 计算y方向边缘(梯度): dx=0,dy=1。
● 计算x方向与y方向的边缘叠加:通过组合方式实现
代码实现
原图显示
# 导入OpenCV库
import cv2
# 从文件中加载图像 'xuezhiqin.png'
image = cv2.imread('xuezhiqin.png')
# 显示加载的图像,窗口标题为 'xuezhiqian'
cv2.imshow('xuezhiqian', image)
# 等待10秒(10000毫秒)以便查看图像
cv2.waitKey(10000)
# 关闭所有打开的OpenCV窗口
cv2.destroyAllWindows()
运行结果:
经过Scharr算子实现
# 导入OpenCV库
import cv2
# 从文件中加载灰度图像
image = cv2.imread('xuezhiqin.png', cv2.IMREAD_GRAYSCALE)
# 对图像进行Scharr滤波操作,计算x方向上的一阶导数
image_x_64 = cv2.Scharr(image, cv2.CV_64F, dx=1, dy=0)
# 将结果转换为绝对值并缩放到8位无符号整数范围内
image_x_full = cv2.convertScaleAbs(image_x_64)
# 再次应用Scharr滤波器,这次计算y方向上的一阶导数
image_y_64 = cv2.Scharr(image, cv2.CV_64F, dx=0, dy=1)
# 将结果转换为绝对值并缩放到8位无符号整数范围内
image_y_full = cv2.convertScaleAbs(image_y_64)
# 将x和y方向上的Scharr滤波结果加权相加,生成最终的Scharr滤波结果
image_xy_Scharr_full = cv2.addWeighted(image_x_full, 1, image_y_full, 1, 0)
# 显示处理后的图像
cv2.imshow('image_xy_Scaharr_full', image_xy_Scharr_full)
# 等待键盘输入,等待100秒后关闭窗口
cv2.waitKey(100000)
运行结果:
scharr算子优缺点
Scharr算子的优点主要有以下几点:
- 高灵敏度:Scharr算子对边缘的检测灵敏度较高,能够准确地检测出图像中的边缘信息。
- 抗噪声能力强:Scharr算子在处理图像时,能够有效地抑制噪声,减少噪声对边缘检测的干扰。
- 精确表征图像局部信息:Scharr算子可以更精确地表征图像的局部信息,例如局部梯度和方向等信息,这样就可以更好地理解和分析图像的局部特性。
然而,Scharr算子也存在一些缺点:
- 运算量大:相比其他算子,Scharr算子的运算量较大,需要更多的计算资源和时间来处理图像。
- 可能产生伪边缘:虽然Scharr算子能够准确地检测出边缘,但在某些情况下,可能会产生伪边缘,这需要适当的后处理来去除这些伪边缘。
- 不适用于所有图像:对于某些具有特定特性的图像,Scharr算子可能无法准确地检测出边缘,因此需要针对具体图像选择合适的算子或算法。