In [1]:
# lets blur a image by calculating the average of neighbor cells
from matplotlib import pyplot as plt
from matplotlib import image
import numpy as np
from scipy import ndimage
from __future__ import division
%matplotlib inline

In [2]:
# get image, use only red channel
img = image.imread('MP.tif')[...,0]

In [3]:
# neighbor mask/footprint
mask = np.array([[1, 1, 1],
                 [1, 1, 1],
                 [1, 1, 1]])

In [4]:
%%time
# take average of every cell
# here mode is how to handle border (default is mirror)
# mode=constant -> cval=const default 0
blur_img = ndimage.generic_filter(img, np.average, footprint=mask) #, mode='constant')


CPU times: user 1min 10s, sys: 11.9 ms, total: 1min 10s
Wall time: 1min 10s

In [5]:
plt.figure(figsize=(13,13))
plt.imshow(blur_img, cmap='gray')
plt.figure()
plt.figure(figsize=(13,13))
plt.imshow(img, cmap='gray')


Out[5]:
<matplotlib.image.AxesImage at 0x7f37448fc550>
<matplotlib.figure.Figure at 0x7f37449e1250>

Comparing the pictures, we see that the averaged picture have less noise. Lets look at a sample of the images and compare.


In [6]:
print img[120:130, 120:130]
print blur_img[120:130, 120:130]


[[ 45  32   6  13  13  20  32  20   6  20]
 [ 32  26  13   6  13   6   6  26   6   0]
 [ 65  45  26  13  13   6   0  13   0  13]
 [112  52  52  20  13  32   6  13  13  26]
 [ 32  59  32  20  45  26  20   6   0   6]
 [ 59  39  26  20  32  13   6  26   0  26]
 [ 45  32  32  32  13  39  26   0  26  13]
 [ 85  59  59  20  13  45  32   6  26  20]
 [ 39  45  39  32  59  13  32  26  26  26]
 [ 65  52  32  59  72  85  39  52  52  13]]
[[32 23 15 11 12 14 16 14 12  8]
 [51 32 20 12 11 12 14 12 11  7]
 [65 47 28 18 13 10 12  9 12 10]
 [63 52 35 26 20 17 13  7 10 11]
 [59 51 35 28 24 21 16 10 12 15]
 [47 39 32 28 26 24 18 12 11 15]
 [57 48 35 27 25 24 21 16 15 19]
 [53 48 38 33 29 30 24 22 18 19]
 [60 52 44 42 44 43 36 32 27 21]
 [52 42 43 49 55 54 48 45 38 30]]

In [7]:
print img.var()
print blur_img.var()


714.107846358
503.928537879

Variance is approximatly 200 less in the averaged image.


In [8]:
%%time
# use specific function convolve instead of generic_filter (speed)
blur_img2 = ndimage.convolve(img, mask/9.)
plt.figure(figsize=(13,13))
plt.imshow(blur_img2, cmap='gray')


CPU times: user 204 ms, sys: 4.02 ms, total: 208 ms
Wall time: 202 ms

In [9]:
np.array_equal(blur_img, blur_img2)


Out[9]:
False

In [10]:
print blur_img[120:130, 120:130]
print blur_img2[120:130, 120:130]


[[32 23 15 11 12 14 16 14 12  8]
 [51 32 20 12 11 12 14 12 11  7]
 [65 47 28 18 13 10 12  9 12 10]
 [63 52 35 26 20 17 13  7 10 11]
 [59 51 35 28 24 21 16 10 12 15]
 [47 39 32 28 26 24 18 12 11 15]
 [57 48 35 27 25 24 21 16 15 19]
 [53 48 38 33 29 30 24 22 18 19]
 [60 52 44 42 44 43 36 32 27 21]
 [52 42 43 49 55 54 48 45 38 30]]
[[32 22 15 11 12 14 16 14 12  8]
 [51 32 19 12 11 12 14 12 11  7]
 [65 47 28 18 13 10 12  9 12 10]
 [63 52 35 26 20 17 13  7  9 11]
 [59 51 35 28 24 21 16 10 12 15]
 [47 39 32 28 26 24 18 12 11 15]
 [57 48 35 27 25 24 21 16 15 19]
 [53 48 38 33 29 30 24 22 18 19]
 [60 52 44 42 44 43 36 32 27 21]
 [52 42 43 49 55 54 48 45 38 30]]

In [11]:
print blur_img.var()
print blur_img2.var()


503.928537879
503.940554973

Seems like some rounding error.


In [12]:
%%time
# +0.1 for rounding, then convert to uint8
blur_img2 = ndimage.convolve(img+0.1, mask/9.).astype(np.uint8)
plt.figure(figsize=(13,13))
plt.imshow(blur_img2, cmap='gray')


CPU times: user 182 ms, sys: 8 ms, total: 190 ms
Wall time: 189 ms

In [13]:
# check if they are the same
np.array_equal(blur_img, blur_img2)


Out[13]:
True

Now we save our refined function to common notebook and use it:


In [87]:
%run common.ipynb
smooth_img = smooth(img)
np.array_equal(blur_img, smooth_img)


Populating the interactive namespace from numpy and matplotlib
Out[87]:
True