简介
本节为《OpenCV计算机视觉实战(Python)》版第五讲,图像梯度处理,的总结。
总结
Sobel算子
Sobel算子:
其计算梯度的过程为:
OpenCV代码:
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth: 图像的深度,默认为-1
- dx,dy: 分别表示水平和竖直方向
- ksize: 表示Sobel算子的大小
# 读入图像
img = cv2.imread('pie.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 计算x轴梯度
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
# 计算y轴梯度
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobely = cv2.convertScaleAbs(sobely)
# 将x和y轴梯度求和
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5,0)
cv2.imshow('sobelx', soblex)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 注意,各种算子的计算,均为:右-左,下-上
- 在相减的过程中,从白到黑的相减,是正数,但是从黑到白的相减是负数,由于像素值被限制在0-255范围内,所有的负数会被截断为0,所以要取绝对值: cv2.convertScaleAbs(sobelx),在取绝对值之前,要将负数形式保存,因此,第二个参数写作:cv2.CV_64F
- 如果同时计算x/y轴的梯度,效果并不好,因此分别做x和y轴的梯度,然后得到加权的结果。
- cv2.addWeighted(sobelx, 0.5, sobely, 0.5,0)中,0.5表示权重;0表示偏置项,不写的话默认为0
Scharr算子
Scharr算子的表达式为:
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
- Scharr算子相比于sobel算子,增大了相邻点的权重
- 带来的结果是,它的梯度信息会更丰富,得到的图像中,细节会更多。
Laplacian算子
Laplacian算子的表达式为:
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
- Laplacian算子,不是计算单x或者单y,而是将当前像素点,与周围像素点相比较,如果该点是边界,那么输出值比较大
- Laplacian算子,对噪声点敏感(因为只考虑了上下左右四个像素点对中间像素点的影响,没有考虑左上左下右上右下点)
- 一般该算子不单独使用
各种算子的比较
# 不同算子的差异
img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Soble(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Soble(img, cv2.CV_64F, 0, 1, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((sobelxy, scharrxy, laplacian))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果: