Merge pull request #138 from poilvert/array_views

ENH: Add window views and montage.
This commit is contained in:
Stefan van der Walt
2012-02-19 00:27:09 -08:00
8 changed files with 696 additions and 2 deletions
+97
View File
@@ -0,0 +1,97 @@
"""
=======================================================
Gabors / Primary Visual Cortex "Simple Cells" from Lena
=======================================================
(under construction)
How to build a (bio-plausible) "sparse" dictionary (or 'codebook', or
'filterbank') for e.g. image classification without any fancy math and
with just standard python scientific libraries?
Please find below a short answer ;-)
This simple example shows how to get Gabor-like filters [1]_ using just
the famous Lena image. Gabor filters are good approximations of the
"Simple Cells" [2]_ receptive fields [3]_ found in the mammalian primary
visual cortex (V1) (for details, see e.g. the Nobel-prize winning work
of Hubel & Wiesel done in the 60s [4]_ [5]_).
Here we use McQueen's 'kmeans' algorithm [6]_, as a simple biologically
plausible hebbian-like learning rule and we apply it (a) to patches of
the original Lena image (retinal projection), and (b) to patches of an
LGN-like [7]_ Lena image using a simple difference of gaussians (DoG)
approximation.
Enjoy ;-) And keep in mind that getting Gabors on natural image patches
is not rocket science.
.. [1] http://en.wikipedia.org/wiki/Gabor_filter
.. [2] http://en.wikipedia.org/wiki/Simple_cell
.. [3] http://en.wikipedia.org/wiki/Receptive_field
.. [4] http://en.wikipedia.org/wiki/K-means_clustering
.. [5] http://en.wikipedia.org/wiki/Lateral_geniculate_nucleus
.. [6] D. H. Hubel and T. N. Wiesel Receptive Fields of Single Neurones
in the Cat's Striate Cortex J. Physiol. pp. 574-591 (148) 1959
.. [7] D. H. Hubel and T. N. Wiesel Receptive Fields, Binocular
Interaction and Functional Architecture in the Cat's Visual Cortex J.
Physiol. 160 pp. 106-154 1962
"""
import numpy as np
from scipy.cluster.vq import kmeans2
from scipy import ndimage as ndi
import matplotlib.pyplot as plt
from skimage import data
from skimage import color
from skimage.util.shape import view_as_windows
from skimage.util.montage import montage2d
np.random.seed(42)
patch_shape = 8, 8
n_filters = 49
lena = color.rgb2gray(data.lena())
# -- filterbank1 on original Lena
patches1 = view_as_windows(lena, patch_shape)
patches1 = patches1.reshape(-1, patch_shape[0] * patch_shape[1])[::8]
fb1, _ = kmeans2(patches1, n_filters, minit='points')
fb1 = fb1.reshape((-1,) + patch_shape)
fb1_montage = montage2d(fb1, rescale_intensity=True)
# -- filterbank2 LGN-like Lena
lena_dog = ndi.gaussian_filter(lena, .5) - ndi.gaussian_filter(lena, 1)
patches2 = view_as_windows(lena_dog, patch_shape)
patches2 = patches2.reshape(-1, patch_shape[0] * patch_shape[1])[::8]
fb2, _ = kmeans2(patches2, n_filters, minit='points')
fb2 = fb2.reshape((-1,) + patch_shape)
fb2_montage = montage2d(fb2, rescale_intensity=True)
# --
plt.figure(figsize=(9, 3))
plt.subplot(2, 2, 1)
plt.imshow(lena, cmap=plt.cm.gray)
plt.axis('off')
plt.title("Lena (original)")
plt.subplot(2, 2, 2)
plt.imshow(fb1_montage, cmap=plt.cm.gray)
plt.axis('off')
plt.title("K-means filterbank (codebook) on Lena (original)")
plt.subplot(2, 2, 3)
plt.imshow(lena_dog, cmap=plt.cm.gray)
plt.axis('off')
plt.title("Lena (LGN-like DoG)")
plt.subplot(2, 2, 4)
plt.imshow(fb2_montage, cmap=plt.cm.gray)
plt.axis('off')
plt.title("K-means filterbank (codebook) on Lena (LGN-like DoG)")
plt.show()
+67
View File
@@ -0,0 +1,67 @@
"""
============================
Block views on images/arrays
============================
This example illustrates the use of `view_as_blocks` from
`skimage.util.shape`. Block views can be incredibly useful when one
wants to perform local operations on non-overlapping image patches.
We use `lena` from `skimage.data` and virtually 'slice' it into square
blocks. Then, on each block, we either pool the mean, the max or the
median value of that block. The results are displayed altogether, along
with a spline interpolation of order 3 rescaling of the original `lena`
image.
"""
import numpy as np
from scipy import ndimage as ndi
from matplotlib import pyplot as plt
import matplotlib.cm as cm
from skimage import data
from skimage import color
from skimage.util.shape import view_as_blocks
# -- get `lena` from skimage.data in grayscale
l = color.rgb2gray(data.lena())
# -- size of blocks
block_shape = (4, 4)
# -- see `lena` as a matrix of blocks (of shape
# `block_shape`)
view = view_as_blocks(l, block_shape)
# -- collapse the last two dimensions in one
flatten_view = view.reshape(view.shape[0], view.shape[1], -1)
# -- resampling `lena` by taking either the `mean`,
# the `max` or the `median` value of each blocks.
mean_view = np.mean(flatten_view, axis=2)
max_view = np.max(flatten_view, axis=2)
median_view = np.median(flatten_view, axis=2)
# -- display resampled images
plt.figure(figsize=(10, 10))
plt.subplot(221)
plt.title("Original rescaled with\n spline interpolation (order=3)")
l_resized = ndi.zoom(l, 2, order=3)
plt.imshow(l_resized, cmap=cm.Greys_r)
plt.subplot(222)
plt.title("Block view with\n local mean pooling")
plt.imshow(mean_view, cmap=cm.Greys_r)
plt.subplot(223)
plt.title("Block view with\n local max pooling")
plt.imshow(max_view, cmap=cm.Greys_r)
plt.subplot(224)
plt.title("Block view with\n local median pooling")
plt.imshow(median_view, cmap=cm.Greys_r)
plt.subplots_adjust(hspace=0.4, wspace=0.4)
plt.show()