Skip to content Skip to sidebar Skip to footer

Difference Between Scipy And Numpy Sobel Gradient Calculation

Setting I am currently trying to calcualte the image gradients with sobel filters. At first I used scipy.ndimage.sobelfunction via sx = ndimage.sobel(im, axis=0,mode='constant')

Solution 1:

Judging by the method names correlate1d and convolve2d I would strongly suspect that the former computes a correlation, whereas the latter computes a convolution. What's the difference?

Generally speaking, a convolution of a signal f with a kernel g involves flipping the kernel before the operation: f*g(-t)

In contrast, a correlation of a signal f with a kernel g is carried out without flipping the kernel: f*g(t)

Applying a directional edge detection kernel (like a sobel kernel) using convolution should therefore result in inverted edges compared to the result using correlation. Let's test this in code:

import numpy as np
from scipy import signal
from PIL import Image
from matplotlib import pyplot as plt

img = Image.open('lena.png')
plt.imshow(img)

enter image description here

First, let's define a sobel edge detection kernel:

g = np.asarray([[-1, 0, 1],
                [-2, 0, 2],
                [-1, 0, 1]])

Now let's first convolve the image with our kernel using sicpy's signal.convolve2d

img_convolved = signal.convolve2d(img, g)
plt.imshow(img_convolved, cmap='gray')

enter image description here

... and zoom in on a edge:

plt.imshow(img_convolved[100:150,100:150], cmap='gray')

enter image description here

Now, let's correlate the image with our kernel using sicpy's signal.correlate2d

img_correlated = signal.correlate2d(img, g)
plt.imshow(img_correlated, cmap='gray')

enter image description here

... and zoom in on a edge:

plt.imshow(img_correlated[100:150,100:150], cmap='gray')

enter image description here

Finally, let's compare the correlation result with what happens if we do a convolution with a flipped kernel:

img_convolved_flipped = signal.convolve2d(img, np.fliplr(g))
plt.imshow(img_convolved, cmap='gray')

enter image description here

... and zoom in on a edge:

plt.imshow(img_convolved_flipped[100:150,100:150], cmap='gray')

enter image description here

So, scipy's signal.correlate2d(img, g) is equivalent to signal.convolve2d(img, np.fliplr(g))

EDIT (Clarification for the 2D code example):

Please note that in the 2D case a convolution of a signal f with a kernel g involves flipping the kernel around both cardinal axes: f*g(-t,-u).

Therefore, in my code I should have actually flipped the filter twice: np.flipud(np.fliplr(g)). I have omitted this since is not necessary for the vertically symmetric sobel filter but keep in mind that this was a special case.

Post a Comment for "Difference Between Scipy And Numpy Sobel Gradient Calculation"