Convolution bluring image - python
Clash 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
@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.
my output always shows: [[1.]] not [[1]] how come?
– Dominik Lemberger
Aug 10 at 10:00