Home > Mobile >  How do I use 1D gradients to compute a 2D Sobel in OpenCV with a different vector norm?
How do I use 1D gradients to compute a 2D Sobel in OpenCV with a different vector norm?

Time:01-31

OpenCV uses an implementation of a enter image description here

This is not the same as the magnitude of the gradient:

enter image description here

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:

I've accepted enter image description here

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.]
  • Related