学习图像梯度,图像边界等
梯度简单来说就是求导。
OpenCV提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr和Lapacian。Sobel,Scharr其实就是求一阶或二阶导。Scharr是对Sobel的部分优化。Laplacian是求二阶导。
1.Sobel算子和Scharr算子
Sobel算子是高斯平滑和微分操作的结合体,所以他的抗噪声能力很好。你可以设定求导的方向(xorder 或 yorder)。还可以设定使用的卷积核大小(ksize)。当ksize=-1时,会使用33 的Scharr滤波器,他的效果要比33的Sobel滤波器好,而且速度相同,所以在使用33滤波器时应该尽量使用Scharr滤波器(一般就用Sobel算子即可)。33 的 Scharr滤波器卷积核如下所示:
2.Laplacian算子
拉普拉斯算子可以使用二阶导数的形式定义,可假设其离散实现类似于二阶Sobel导数。事实上,OpenCV在计算拉普拉斯算子时直接调用Sobel算子,具体计算公式如下:
拉普拉斯滤波器使用的卷积核:
代码实现:
import cv2 as cv
import numpy as np
#拉普拉斯算子
def lapalian_demo(image):
#Laplacian 算子
#dst = cv.Laplacian(image, cv.CV_32F)
#lpls = cv.convertScaleAbs(dst)
#定义卷积和:八邻域为增强型(可用四邻域[[0, 1, 0], [1, -4, 1], [0, 1, 0]])
kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
dst = cv.filter2D(image, cv.CV_32F, kernel=kernel)
# 把里面的负数转为正数,变成三通道的0-255的图像
lpls = cv.convertScaleAbs(dst)
cv.imshow("lapalian_demo", lpls)
#sobel算子
def sobel_demo(image):
#cv.CV_32F:深度 在x方向求一阶导数
#grad_x = cv.sobel(image, cv.CV_32F, 1, 0)
#grad_y = cv.sobel(image, cv.CV_32F, 0, 1)
#Scharr是sobel的增强算子
grad_x = cv.Scharr(image, cv.CV_32F, 1, 0)
grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)
#把里面的负数转为正数,变成三通道的0-255的图像,x方向梯度
gradx = cv.convertScaleAbs(grad_x)
# y方向梯度
grady = cv.convertScaleAbs(grad_y)
cv.imshow("gradient-x", gradx)
cv.imshow("gradient-y", grady)
gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)
cv.imshow("gradient", gradxy)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("D:/vcprojects/images/test.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
lapalian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()