OpenCV uses an implementation of a
This is not the same as the magnitude of the gradient:
where x(I) = X
directional derivative from the Sobel,
y(I) = Y
directional derivative from the Sobel with
I
= src and magnitude = dst
If you want the L1 norm, then in place of the square root magnitude above, use
magnitude(I) = |x(I)| |y(I)|
where x(I) = X
directional derivative and y(I) = Y
directional derivative (from Sobel) and I
= src and magnitude = dot
CodePudding user response:
import cv2
import numpy as np
z_img = cv2.imread("lena_gray.png")
z_px_rows = z_img.shape[0]
z_px_cols = z_img.shape[1]
kernel_x = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
kernel_y = np.array([[-1, -2, -1],
[ 0, 0, 0],
[ 1, 2, 1]])
# matrix multiply
kernel_xy1 = np.matmul(kernel_x,kernel_y)
kernel_xy2 = np.matmul(kernel_x,kernel_y)
# element-wise multiply
kernel_xy3 = cv2.multiply(kernel_x,kernel_y)
kernel_xy4 = cv2.multiply(kernel_y,kernel_x)
print('')
print("kernel_xy1:\n", kernel_xy1)
print('')
print("kernel_xy2:\n", kernel_xy1)
print('')
print("kernel_xy3:\n", kernel_xy1)
print('')
print("kernel_xy4:\n", kernel_xy1)
print('')
gx = cv2.filter2D(src=z_img, ddepth=cv2.CV_32F, kernel=kernel_x)
print(f'Center pixel intensity (gx): {gx[z_px_rows // 2, z_px_cols // 2]}')
native_sobel_x = cv2.Sobel(z_img, cv2.CV_32F, 1, 0, ksize=3)
print(f'Center pixel intensity (native sobel x): {native_sobel_x[z_px_rows // 2, z_px_cols // 2]}')
gy = cv2.filter2D(src=z_img, ddepth=cv2.CV_32F, kernel=kernel_y)
print(f'Center pixel intensity (gy): {gy[z_px_rows // 2, z_px_cols // 2]}')
native_sobel_y = cv2.Sobel(z_img, cv2.CV_32F, 0, 1, ksize=3)
print(f'Center pixel intensity (native sobel y): {native_sobel_y[z_px_rows // 2, z_px_cols // 2]}')
mixed1 = cv2.filter2D(src=z_img, ddepth=cv2.CV_32F, kernel=kernel_xy1)
print(f'Center pixel intensity (mixed1 - matrix multiply): {mixed1[z_px_rows // 2, z_px_cols // 2]}')
mixed2 = cv2.filter2D(src=z_img, ddepth=cv2.CV_32F, kernel=kernel_xy2)
print(f'Center pixel intensity (mixed2 - matrix multiply): {mixed2[z_px_rows // 2, z_px_cols // 2]}')
mixed3 = cv2.filter2D(src=z_img, ddepth=cv2.CV_32F, kernel=kernel_xy3)
print(f'Center pixel intensity (mixed3 - element-wise multiply): {mixed3[z_px_rows // 2, z_px_cols // 2]}')
mixed4 = cv2.filter2D(src=z_img, ddepth=cv2.CV_32F, kernel=kernel_xy4)
print(f'Center pixel intensity (mixed4 - element-wise multiply): {mixed4[z_px_rows // 2, z_px_cols // 2]}')
native_sobel_xy = cv2.Sobel(z_img, cv2.CV_32F, 1, 1, ksize=3)
print(f'Center pixel intensity (native sobel xy): {native_sobel_xy[z_px_rows // 2, z_px_cols // 2]}')
Results:
kernel_xy1:
[[2 4 2]
[4 8 4]
[2 4 2]]
kernel_xy2:
[[2 4 2]
[4 8 4]
[2 4 2]]
kernel_xy3:
[[2 4 2]
[4 8 4]
[2 4 2]]
kernel_xy4:
[[2 4 2]
[4 8 4]
[2 4 2]]
Center pixel intensity (gx): [6. 6. 6.]
Center pixel intensity (native sobel x): [6. 6. 6.]
Center pixel intensity (gy): [-184. -184. -184.]
Center pixel intensity (native sobel y): [-184. -184. -184.]
Center pixel intensity (mixed1 - matrix multiply): [2580. 2580. 2580.]
Center pixel intensity (mixed2 - matrix multiply): [2580. 2580. 2580.]
Center pixel intensity (mixed3 - element-wise multiply): [-28. -28. -28.]
Center pixel intensity (mixed4 - element-wise multiply): [-28. -28. -28.]
Center pixel intensity (native sobel xy): [-28. -28. -28.]