How can one smooth elements of a two-dimensional array with various gaussian functions in python?

How can I smooth the elements x [1,3] and x [3,2] of an array,

x = np.array([[0,0,0,0,0],[0,0,0,1,0],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0]]) 

with two two-dimensional Gaussian functions of width 1 and 2, respectively? In essence, I need a function that allows me to smooth out individual elements of a point-to-point array with gausses of different widths, so that I get an array with smoothly changing values.

+5
source share
1 answer

I'm a little confused by the question you asked and the comments you posted. It seems to me that you want to use scipy.ndimage.filters.gaussian_filter , but I do not understand what you mean by this:

[...] Gaussian functions with different sigma values โ€‹โ€‹for each pixel. [...]

In fact, since you are using a 2-dimensional array of x , the Gaussian filter will have 2 parameters. Rule: one sigma value for each dimension, not one sigma value per pixel.

Here is a quick example:

 import matplotlib.pyplot as pl import numpy as np import scipy as sp import scipy.ndimage n = 200 # widht/height of the array m = 1000 # number of points sigma_y = 3.0 sigma_x = 2.0 # Create input array x = np.zeros((n, n)) i = np.random.choice(range(0, n * n), size=m) x[i / n, i % n] = 1.0 # Plot input array pl.imshow(x, cmap='Blues', interpolation='nearest') pl.xlabel("$x$") pl.ylabel("$y$") pl.savefig("array.png") # Apply gaussian filter sigma = [sigma_y, sigma_x] y = sp.ndimage.filters.gaussian_filter(x, sigma, mode='constant') # Display filtered array pl.imshow(y, cmap='Blues', interpolation='nearest') pl.xlabel("$x$") pl.ylabel("$y$") pl.title("$\sigma_x = " + str(sigma_x) + "\quad \sigma_y = " + str(sigma_y) + "$") pl.savefig("smooth_array_" + str(sigma_x) + "_" + str(sigma_y) + ".png") 

Here is the source array:

enter image description here

Below are some results for different sigma_x and sigma_y :

enter image description here

enter image description here

enter image description here

enter image description here

This allows you to correctly take into account the influence of the second parameter scipy.ndimage.filters.gaussian_filter .

However, according to the previous quote, you may be more interested in understanding the different weights for each pixel. In this case, the scipy.ndimage.filters.convolve function is the function you are looking for. Here is an example:

 import matplotlib.pyplot as pl import numpy as np import scipy as sp import scipy.ndimage # Arbitrary weights weights = np.array([[0, 0, 1, 0, 0], [0, 2, 4, 2, 0], [1, 4, 8, 4, 1], [0, 2, 4, 2, 0], [0, 0, 1, 0, 0]], dtype=np.float) weights = weights / np.sum(weights[:]) y = sp.ndimage.filters.convolve(x, weights, mode='constant') # Display filtered array pl.imshow(y, cmap='Blues', interpolation='nearest') pl.xlabel("$x$") pl.ylabel("$y$") pl.savefig("smooth_array.png") 

And the corresponding result:

enter image description here

Hope this helps you.

+3
source

Source: https://habr.com/ru/post/1235309/


All Articles