前面学习了Sobel算子,它是高斯平滑与差分的组合,那么把Sobel算子的三阶表示再改进一下,改为下面这样:
左边算子反映垂直方向的边缘,右边算子反映水平方向的边缘。由于Scharr算子比Sobel算子的数值要大,因此对于灰度变化较为敏感,会得到较强的边缘强度,不过细节就会不太好。
例子演示如下:
#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np
from scipy import signal
#图片的路径
imgname = "edge1.png"
#读取图片
image = cv2.imread(imgname, cv2.IMREAD_GRAYSCALE)
#图片的高度和宽度
h,w = image.shape[:2]
print('imagesize={}-{}'.format(w,h))
#显示原图
cv2.imshow("Image",image)
#算子
roberts_cross_h = np.array( [[ -3, -10, -3 ],
[ 0, 0, 0 ],
[ 3, 10, 3 ]] )
roberts_cross_v = np.array( [[ -3, 0, 3 ],
[ -10, 0, 10 ],
[ -3, 0, 3 ]] )
#
vertical = signal.convolve2d(image, roberts_cross_v,boundary='symm')
vertical1 = vertical.astype(np.uint8)
cv2.imshow("vertical",vertical1)
horizontal = signal.convolve2d(image, roberts_cross_h,boundary='symm')
horizontal1 = horizontal .astype(np.uint8)
cv2.imshow("horizontal",horizontal1)
#output_image = np.sqrt( np.square(horizontal) + np.square(vertical))
absX = cv2.convertScaleAbs(horizontal) # 转回uint8
absY = cv2.convertScaleAbs(vertical)
output_image = cv2.addWeighted(absX,0.5,absY,0.5,0)#线性插值
output_image = output_image.astype(np.uint8)
cv2.imshow("output_image",output_image)
#opencv Scharr()
x = cv2.Scharr(image,cv2.CV_64F,1,0)
y = cv2.Scharr(image,cv2.CV_64F,0,1)
absX = cv2.convertScaleAbs(x) # 转回uint8
absY = cv2.convertScaleAbs(y)
ScharrXY = cv2.addWeighted(absX,0.5,absY,0.5,0)#线性插值
cv2.imshow("ScharrXY",ScharrXY)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果输出如下:
输出图片
水平输出图片
垂直输出图片
使用自定义卷积输出
调用OpenCV里Scharr函数
Scharr函数来定义如下:
其中参数:
src 输入图像
dst 输出图像
ddepth 输出图像的深度。
dx x方向差分阶数
dy y方向差分阶数
scale 计算导数时可缩放系数,默认为1.
delta 可选的量值,用于加到导数计算结果中。
borderType 边界类型,默认值为BORDER_DEFAULT
https://blog.csdn.net/caimouse/article/details/51749579
转载:https://blog.csdn.net/caimouse/article/details/102134657
查看评论