Convolution bluring image - python

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Convolution bluring image - python



I have this code below which is almost working - only thing I need here is the output of the convolution has to be devided by 9 and rounded down. Is this somehow possible with convolve2d?


import scipy
import scipy.signal
import numpy as np

def boxBlur(image):
matrix = np.array(image)
W = np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
np.pad(matrix, 1, mode='constant')
return scipy.signal.convolve2d(matrix, W, mode='valid')



So for this example:


boxBlur([[1,1,1],[1,7,1],[1,1,1]])



The output right now is [[15]] but it should be [[1]] (15/9=1,6666 rounded down=1)



Is there a way to not only use the convolve image on the matrix, but also do something else.



Right now the way I managed the problem is to manually go over the array and devide every cell by 9 rounding it down




1 Answer
1



That's called uniform filtetring, hence use SciPy's uniform_filter, which should be faster as well -


uniform_filter


from scipy.ndimage import uniform_filter

uniform_filter(image.astype(float))[1:-1,1:-1]



Sample run -


In [38]: np.random.seed(0)
...: image = np.random.randint(0,9,(7,7))

In [39]: boxBlur(image)/9.0
Out[39]:
array([[4.55555556, 5. , 5.55555556, 5.44444444, 5.11111111],
[4.44444444, 5. , 5. , 4.88888889, 4.22222222],
[4.33333333, 4.44444444, 3.44444444, 3.44444444, 3.77777778],
[2.22222222, 2.55555556, 2.88888889, 3.44444444, 3.55555556],
[2.44444444, 2.11111111, 2.44444444, 3.55555556, 4.33333333]])

In [40]: uniform_filter(image.astype(float))[1:-1,1:-1]
Out[40]:
array([[4.55555556, 5. , 5.55555556, 5.44444444, 5.11111111],
[4.44444444, 5. , 5. , 4.88888889, 4.22222222],
[4.33333333, 4.44444444, 3.44444444, 3.44444444, 3.77777778],
[2.22222222, 2.55555556, 2.88888889, 3.44444444, 3.55555556],
[2.44444444, 2.11111111, 2.44444444, 3.55555556, 4.33333333]])



Timings -


In [42]: np.random.seed(0)
...: image = np.random.randint(0,9,(7000,7000))

In [43]: %timeit boxBlur(image)/9.0
1 loop, best of 3: 2.11 s per loop

In [44]: %timeit uniform_filter(image.astype(float))[1:-1,1:-1]
1 loop, best of 3: 612 ms per loop



Rounding down



For rounding it down, with the original solution, it would be : boxBlur(image)//9. The equivalent one here would be with floor-ing, so use np.floor(), but that might have precision issues. So, we might instead use np.round with a given number of decimal places for the precision and then floor with .astype(int) -


boxBlur(image)//9


np.floor()


np.round


.astype(int)


n = 10 # number of decimal places for precision
np.around(uniform_filter(image.astype(float))[1:-1,1:-1], decimals=n).astype(int)



For an input with ints, another way could be to scale up by 9 and round and then floor -


9


np.round(uniform_filter(image.astype(float))[1:-1,1:-1]*9)//9





my output always shows: [[1.]] not [[1]] how come?
– Dominik Lemberger
Aug 10 at 10:00





@DominikLemberger Because the output is of float dtype. So, convert to int dtype with .astype(int).
– Divakar
Aug 10 at 10:01


.astype(int)





tried that. still shows [[1.]]
– Dominik Lemberger
Aug 10 at 10:02





@DominikLemberger out = np.floor(uniform_filter(image.astype(float))[1:-1,1:-1]).astype(int)?
– Divakar
Aug 10 at 10:02


out = np.floor(uniform_filter(image.astype(float))[1:-1,1:-1]).astype(int)





thanks for the round option - works for all unit tests and I reported a bug on the numpy github as there should be no problem with full integers and .floor ... because there is no need to round anything even once
– Dominik Lemberger
Aug 10 at 10:23






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS