图像梯度
把图片想象成连续函数,因为边缘部分的像素值是与旁边像素明显有区别的,所以对图片局部求极值,就可以得到整幅图片的边缘信息了。不过图片是二维的离散函数,导数就变成了差分,这个差分就称为图像的梯度。
对于具体算子以及求导推导见此博文[https://blog.csdn.net/qq_18815817/article/details/78625845]
1.Sobel 算子
x方向Sobel算子
y方向Sobel算子
Sobel 代码实现
import cv2 as cv
def sobel_demo(image):
# 由于进行对卷积核卷积后的结果值可能会超过八位,故需要设置数据的类型为cv.CV_32F
grad_x = cv.Scharr(image, cv.CV_32F, 1, 0)
grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)
# 线性变换转换输入数组元素成8位无符号整型
gradx = cv.convertScaleAbs(grad_x)
grady = cv.convertScaleAbs(grad_y)
cv.imshow("gradient-x", gradx)
cv.imshow("gradient-y", grady)
# 将x和y方向上的合在一起
gradxy = cv.addWeighted(gradx, 1, grady, 1, 0)
cv.imshow("gradxy", gradxy)
src = cv.imread("girl.jpg")
cv.imshow("girl", src)
sobel_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
图2,3,4分别是对应X,Y,X和Y整体方向梯度的图,图2可能明确看到水平方向让的边缘,图3可以看到竖直方向上的边缘。
Laplacian算子
Laplacian算子则是进行求二阶导的结果的算子。
这就是Laplacian算子的图像卷积模板,有些资料中在此基础上考虑斜对角情况,将卷积核拓展为:
Laplacian代码实现
import cv2 as cv
def laplacian_demo(image):
dst = cv.Laplacian(image, cv.CV_32F)
lpls = cv.convertScaleAbs(dst)
cv.imshow("laplacian_demo", lpls)
src = cv.imread("girl.jpg")
cv.imshow("girl", src)
laplacian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
代码实现
import cv2 as cv
import numpy as np
def laplacian_demo(image):
kernel = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
dst = cv.filter2D(image, cv.CV_32F, kernel = kernel)
lpls = cv.convertScaleAbs(dst)
cv.imshow("laplacian_demo", lpls)
src = cv.imread("girl.jpg")
cv.imshow("girl", src)
# sobel_demo(src)
laplacian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
初学Opencv,如有错误地方和改进地方,真诚地邀请您提出来,谢谢!
本文结束…