Sobel算子
纵向算子
横向算子
参数ddepth
在实际操作中,计算梯度值可能会出现负数。如果处理的图像是8位图类型,则在ddepth的参数值为-1时,意味着指定运算结果也是8位图类型,那么所有负数会自动截断位0,发生了信息丢失。
为了避免信息丢失,在计算时要先使用更高的数据类型cv2.CV_64F,再通过取绝对值将其映射为cv2.CV_8U(8位图)类型。所以,通常要将函数cv2.Sobel()内参数ddepth的值设置为“cv2.CV_64F”。
1 2 3
| import cv2 import numpy as np from get_show_img import get_show
|
1
| img = np.random.randint(-256, 256, size=[4, 5])
|
array([[ -39, 94, 94, -143, -75],
[-131, -60, -5, 162, -148],
[ -68, 22, 234, 84, -242],
[ 111, 117, 115, -120, -52]])
1
| rst = cv2.convertScaleAbs(img)
|
array([[ 39, 94, 94, 143, 75],
[131, 60, 5, 162, 148],
[ 68, 22, 234, 84, 242],
[111, 117, 115, 120, 52]], dtype=uint8)
方向
计算x方向边缘(梯度) dx=1, dy=0
1
| src = cv2.imread('data/sobel4.bmp')
|
1 2
| dst = cv2.Sobel(src, -1, 1, 0) get_show(dst)
|
1 2 3
| dst = cv2.Sobel(src,cv2.CV_64F, 1, 0) dst = cv2.convertScaleAbs(dst) get_show(dst)
|
计算y方向边缘(梯度) dx=0, dy=1
1 2
| dst = cv2.Sobel(src, -1, 0, 1) get_show(dst)
|
1 2 3
| dst = cv2.Sobel(src,cv2.CV_64F, 0, 1) dst = cv2.convertScaleAbs(dst) get_show(dst)
|
dx和dy方向边缘(梯度) dx=1, dy=1
1 2
| dst = cv2.Sobel(src, -1, 1, 1) get_show(dst)
|
1 2 3
| dst = cv2.Sobel(src,cv2.CV_64F, 1, 1) dst = cv2.convertScaleAbs(dst) get_show(dst)
|
计算x方向和y方向的边缘叠加
1 2 3 4
| dx = cv2.Sobel(src, -1, 1, 0) dy = cv2.Sobel(src, -1, 0, 1) dst = cv2.addWeighted(dx, 0.5, dy, 0.5, 0) get_show(dst)
|
1 2 3 4 5 6
| dx = cv2.Sobel(src, cv2.CV_64F, 1, 0) dy = cv2.Sobel(src, cv2.CV_64F, 0, 1) dx = cv2.convertScaleAbs(dx) dy = cv2.convertScaleAbs(dy) dst = cv2.addWeighted(dx, 0.5, dy, 0.5, 0) get_show(dst)
|
array([ 0, 128, 255], dtype=uint8)
针对具体图像
1 2 3 4 5 6 7 8 9
| src = cv2.imread('data/dog1.jpg', 0) dx = cv2.Sobel(src, cv2.CV_64F, 1, 0) dy = cv2.Sobel(src, cv2.CV_64F, 0, 1) dx = cv2.convertScaleAbs(dx) dy = cv2.convertScaleAbs(dy) dst = cv2.addWeighted(dx, 0.5, dy, 0.5, 0) dst1 = cv2.Sobel(src,cv2.CV_64F, 1, 1) dst1 = cv2.convertScaleAbs(dst1) get_show(src, dst, dst1)
|
Scharr算子
纵向算子
横向算子
计算x方向边缘(梯度) dx=1, dy=0
1
| src = cv2.imread('data/sobel4.bmp')
|
1 2 3
| dst = cv2.Scharr(src, cv2.CV_64F, 1, 0) dst = cv2.convertScaleAbs(dst) get_show(dst)
|
计算y方向边缘(梯度) dx=0, dy=1
1 2 3
| dst = cv2.Scharr(src, cv2.CV_64F, 0, 1) dst = cv2.convertScaleAbs(dst) get_show(dst)
|
计算x方向和y方向的边缘叠加
1 2 3 4 5 6
| dx = cv2.Scharr(src, cv2.CV_64F, 1, 0) dy = cv2.Scharr(src, cv2.CV_64F, 0, 1) dx = cv2.convertScaleAbs(dx) dy = cv2.convertScaleAbs(dy) dst = cv2.addWeighted(dx, 0.5, dy, 0.5, 0) get_show(dst)
|
Sobel算子和Scharr算子叠加
Sobel算子的缺点是,当其核结构较小时,精确度不高,而Scharr算子具有更高的精度。
1
| rst = cv2.imread('data/dog1.jpg', 0)
|
1 2 3 4 5 6 7 8 9 10
| sobelx = cv2.Sobel(rst, cv2.CV_64F, 1, 0, ksize=3) sobely = cv2.Sobel(rst, 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(rst, cv2.CV_64F, 1, 0) scharry = cv2.Scharr(rst, cv2.CV_64F, 0, 1) scharrx = cv2.convertScaleAbs(scharrx) scharry = cv2.convertScaleAbs(scharry) scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
|
1
| get_show(rst, sobelxy, scharrxy)
|
Laplacian(拉普拉斯)算子
1 2
| laplacian = cv2.Laplacian(rst, cv2.CV_64F, ksize=3) laplacian = cv2.convertScaleAbs(laplacian)
|
1
| get_show(rst, laplacian)
|