26

I want to apply a Gaussian filter of dimension 5x5 pixels on an image of 512x512 pixels. I found a scipy function to do that:

scipy.ndimage.filters.gaussian_filter(input, sigma, truncate=3.0)

How I choose the parameter of sigma to make sure that my Gaussian window is 5x5 pixels?

user2863620
  • 635
  • 3
  • 10
  • 17

2 Answers2

43

Check out the source code here: https://github.com/scipy/scipy/blob/master/scipy/ndimage/filters.py

You'll see that gaussian_filter calls gaussian_filter1d for each axis. In gaussian_filter1d, the width of the filter is determined implicitly by the values of sigma and truncate. In effect, the width w is

w = 2*int(truncate*sigma + 0.5) + 1

So

(w - 1)/2 = int(truncate*sigma + 0.5)

For w = 5, the left side is 2. The right side is 2 if

2 <= truncate*sigma + 0.5 < 3

or

1.5 <= truncate*sigma < 2.5

If you choose truncate = 3 (overriding the default of 4), you get

0.5 <= sigma < 0.83333...

We can check this by filtering an input that is all 0 except for a single 1 (i.e. find the impulse response of the filter) and counting the number of nonzero values in the filtered output. (In the following, np is numpy.)

First create an input with a single 1:

In [248]: x = np.zeros(9)

In [249]: x[4] = 1

Check the change in the size at sigma = 0.5...

In [250]: np.count_nonzero(gaussian_filter1d(x, 0.49, truncate=3))
Out[250]: 3

In [251]: np.count_nonzero(gaussian_filter1d(x, 0.5, truncate=3))
Out[251]: 5

... and at sigma = 0.8333...:

In [252]: np.count_nonzero(gaussian_filter1d(x, 0.8333, truncate=3))
Out[252]: 5

In [253]: np.count_nonzero(gaussian_filter1d(x, 0.8334, truncate=3))
Out[253]: 7
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • 1
    Your answer differs from this answer of this question: [link](https://stackoverflow.com/questions/29920114/how-to-gauss-filter-blur-a-floating-point-numpy-array) therefore I have asked another question. Maybe your could clarify for me whats right and whats wrong? [My question:](https://stackoverflow.com/questions/44695712/how-to-use-a-gaussian-filter-of-5-along-an-axis-in-a-3-dimensional-array-in-pyth) –  Jun 22 '17 at 09:42
  • Just a note: a Gaussian with a sigma of 0.5, when sampled, leads to a large degree of aliasing. The sampled kernel no longer resembles a Gaussian. Larger values are needed for proper Gaussian filtering. A sigma of 1.0 leads to a 1% of the power of the kernel being aliased. So depending on your tolerance for precision, you might accept slightly smaller Gaussians too, maybe down to 0.8 or so, but lower that that it no longer makes sense. – Cris Luengo Apr 30 '20 at 17:26
17

Following the excellent previous answer:

  1. set sigma s = 2
  2. set window size w = 5
  3. evaluate the 'truncate' value: t = (((w - 1)/2)-0.5)/s
  4. filtering: filtered_data = scipy.ndimage.filters.gaussian_filter(data, sigma=s, truncate=t)
Jérôme
  • 1,254
  • 2
  • 20
  • 25
Gustavo Ortiz
  • 171
  • 1
  • 2