I have got a numpy array a
of type float64
. How can I blur this data with a Gauss filter?
I have tried
from PIL import Image, ImageFilter
image = Image.fromarray(a)
filtered = image.filter(ImageFilter.GaussianBlur(radius=7))
, but this yields ValueError: 'image has wrong mode'
. (It has mode F
.)
I could create an image of suitable mode by multiplying a
with some constant, then rounding to integer. That should work, but I would like to have a more direct way.
(I am using Pillow 2.7.0.)
Syntax – cv2 GaussianBlur() function[height width]. height and width should be odd and can have different values. If ksize is set to [0 0], then ksize is computed from sigma values. Kernel standard deviation along X-axis (horizontal direction).
Gaussian Kernel/Filter:Create a function named gaussian_kernel() , which takes mainly two parameters. The size of the kernel and the standard deviation. array([-2., -1., 0., 1., 2.]) Then we will create the outer product and normalize to make sure the center value is always 1.
In a Gaussian blur, the pixels nearest the centre of the kernel are given more weight than those far away from the centre. This averaging is done on a channel-by-channel basis, and the average channel values become the new value for the pixel in the filtered image.
If you have a two-dimensional numpy array a
, you can use a Gaussian filter on it directly without using Pillow to convert it to an image first. scipy has a function gaussian_filter
that does the same.
from scipy.ndimage.filters import gaussian_filter blurred = gaussian_filter(a, sigma=7)
Purely numpy solution using convolve and the separability of the Gaussian filter into two separate filter steps (which makes it relatively fast):
kernel = np.array([1.0,2.0,1.0]) # Here you would insert your actual kernel of any size
a = np.apply_along_axis(lambda x: np.convolve(x, kernel, mode='same'), 0, a)
a= np.apply_along_axis(lambda x: np.convolve(x, kernel, mode='same'), 1, a)
Here is my approach using only numpy. It is prepared with a simple 3x3 kernel, minor changes could make it work with custom sized kernels.
def blur(a):
kernel = np.array([[1.0,2.0,1.0], [2.0,4.0,2.0], [1.0,2.0,1.0]])
kernel = kernel / np.sum(kernel)
arraylist = []
for y in range(3):
temparray = np.copy(a)
temparray = np.roll(temparray, y - 1, axis=0)
for x in range(3):
temparray_X = np.copy(temparray)
temparray_X = np.roll(temparray_X, x - 1, axis=1)*kernel[y,x]
arraylist.append(temparray_X)
arraylist = np.array(arraylist)
arraylist_sum = np.sum(arraylist, axis=0)
return arraylist_sum
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With