.. only:: html
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy import ndimage
.. _image-answers:
Example of solution for the image processing exercise: unmolten grains in glass
===============================================================================
.. image:: ../image_processing/MV_HFV_012.jpg
:align: center
1. Open the image file MV_HFV_012.jpg and display it. Browse through the
keyword arguments in the docstring of ``imshow`` to display the image
with the "right" orientation (origin in the bottom left corner, and not
the upper left corner as for standard arrays). ::
>>> dat = plt.imread('data/MV_HFV_012.jpg')
2. Crop the image to remove the lower panel with measure information. ::
>>> dat = dat[:-60]
3. Slightly filter the image with a median filter in order to refine its
histogram. Check how the histogram changes. ::
>>> filtdat = ndimage.median_filter(dat, size=(7,7))
>>> hi_dat = np.histogram(dat, bins=np.arange(256))
>>> hi_filtdat = np.histogram(filtdat, bins=np.arange(256))
.. image:: ../image_processing/exo_histos.png
:align: center
4. Using the histogram of the filtered image, determine thresholds that
allow to define masks for sand pixels, glass pixels and bubble pixels.
Other option (homework): write a function that determines automatically
the thresholds from the minima of the histogram. ::
>>> void = filtdat <= 50
>>> sand = np.logical_and(filtdat > 50, filtdat <= 114)
>>> glass = filtdat > 114
5. Display an image in which the three phases are colored with three
different colors. ::
>>> phases = void.astype(np.int) + 2*glass.astype(np.int) + 3*sand.astype(np.int)
.. image:: ../image_processing/three_phases.png
:align: center
6. Use mathematical morphology to clean the different phases. ::
>>> sand_op = ndimage.binary_opening(sand, iterations=2)
7. Attribute labels to all bubbles and sand grains, and remove from the
sand mask grains that are smaller than 10 pixels. To do so, use
``ndimage.sum`` or ``np.bincount`` to compute the grain sizes. ::
>>> sand_labels, sand_nb = ndimage.label(sand_op)
>>> sand_areas = np.array(ndimage.sum(sand_op, sand_labels, np.arange(sand_labels.max()+1)))
>>> mask = sand_areas > 100
>>> remove_small_sand = mask[sand_labels.ravel()].reshape(sand_labels.shape)
.. image:: ../image_processing/sands.png
:align: center
8. Compute the mean size of bubbles. ::
>>> bubbles_labels, bubbles_nb = ndimage.label(void)
>>> bubbles_areas = np.bincount(bubbles_labels.ravel())[1:]
>>> mean_bubble_size = bubbles_areas.mean()
>>> median_bubble_size = np.median(bubbles_areas)
>>> mean_bubble_size, median_bubble_size
(1699.875, 65.0)