I have a binary array, say, a = np.random.binomial(n=1, p=1/2, size=(9, 9))
. I perform median filtering on it using a 3 x 3
kernel on it, like say, b = nd.median_filter(a, 3)
. I would expect that this should perform median filter based on the pixel and its eight neighbours. However, I am not sure about the placement of the kernel. The documentation says,
origin : scalar, optional.
The origin parameter controls the placement of the filter. Default 0.0.
If the default were zero, it should be taking the current pixel and the 3 x 3
grid to the right and bottom, no? Shouldn't the default be the center of the footprint
? Which in our 3 x 3
example would correspond to (1, 1)
as opposed to (0, 0)
?
Thanks.
origin says it accepts only a scalar, but for me it also accepts array-like input as also the case for the scipy.ndimage.filters.convolve function. Passing 0 is indeed the center of the footprint. Origin's value is relative to the center. With a 3x3 footprint, you can specify values -1.0 to 1.0. Here are some examples. Notice in the example with origin not specified that the filter is centered as expected.
import numpy as np
import scipy.ndimage
a= np.zeros((5, 5))
a[1:4, 1:4] = np.arange(3*3).reshape((3, 3))
default_out = scipy.ndimage.median_filter(a, size=(3, 3))
shift_pos_x = scipy.ndimage.median_filter(a, size=(3, 3), origin=(0, 1))
shift_neg_x = scipy.ndimage.median_filter(a, size=(3, 3), origin=(0, -1))
print(a)
print(default_out)
print(shift_pos_x)
print(shift_neg_x)
Output:
Input Array:
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 1. 2. 0.]
[ 0. 3. 4. 5. 0.]
[ 0. 6. 7. 8. 0.]
[ 0. 0. 0. 0. 0.]]
Centered Output:
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 1. 0. 0.]
[ 0. 1. 4. 2. 0.]
[ 0. 0. 4. 0. 0.]
[ 0. 0. 0. 0. 0.]]
Shifted To Right Output:
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 1. 0.]
[ 0. 0. 1. 4. 2.]
[ 0. 0. 0. 4. 0.]
[ 0. 0. 0. 0. 0.]]
Shifted To Left Output:
[[ 0. 0. 0. 0. 0.]
[ 0. 1. 0. 0. 0.]
[ 1. 4. 2. 0. 0.]
[ 0. 4. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]