Difference Between Scipy And Numpy Sobel Gradient Calculation
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)
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')
... and zoom in on a edge:
plt.imshow(img_convolved[100:150,100:150], cmap='gray')
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')
... and zoom in on a edge:
plt.imshow(img_correlated[100:150,100:150], cmap='gray')
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')
... and zoom in on a edge:
plt.imshow(img_convolved_flipped[100:150,100:150], cmap='gray')
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"