Files
scikit-image/skimage/util/montage.py
T
Johannes Schönberger 3e3a52331d Misc doc string fixes
2013-10-02 17:07:23 +02:00

110 lines
3.1 KiB
Python

__all__ = ['montage2d']
import numpy as np
from .. import exposure
EPSILON = 1e-6
def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=None):
"""Create a 2-dimensional 'montage' from a 3-dimensional input array
representing an ensemble of equally shaped 2-dimensional images.
For example, ``montage2d(arr_in, fill)`` with the following `arr_in`
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
will return:
+---+---+
| 1 | 2 |
+---+---+
| 3 | * |
+---+---+
Where the '*' patch will be determined by the `fill` parameter.
Parameters
----------
arr_in: ndarray, shape=[n_images, height, width]
3-dimensional input array representing an ensemble of n_images
of equal shape (i.e. [height, width]).
fill: float or 'mean', optional
How to fill the 2-dimensional output array when sqrt(n_images)
is not an integer. If 'mean' is chosen, then fill = arr_in.mean().
rescale_intensity: bool, optional
Whether to rescale the intensity of each image to [0, 1].
grid_shape: tuple, optional
The desired grid shape for the montage (tiles_y, tiles_x).
The default aspect ratio is square.
Returns
-------
arr_out: ndarray, shape=[alpha * height, alpha * width]
Output array where 'alpha' has been determined automatically to
fit (at least) the `n_images` in `arr_in`.
Examples
--------
>>> import numpy as np
>>> from skimage.util.montage import montage2d
>>> arr_in = np.arange(3 * 2 * 2).reshape(3, 2, 2)
>>> print(arr_in) # doctest: +NORMALIZE_WHITESPACE
[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]]]
>>> arr_out = montage2d(arr_in)
>>> print(arr_out.shape)
(4, 4)
>>> print(arr_out)
[[ 0. 1. 4. 5. ]
[ 2. 3. 6. 7. ]
[ 8. 9. 5.5 5.5]
[ 10. 11. 5.5 5.5]]
>>> print(arr_in.mean())
5.5
>>> arr_out_nonsquare = montage2d(arr_in, grid_shape=(3, 4))
>>> print(arr_out_nonsquare)
[[ 0. 1. 4. 5. ]
[ 2. 3. 6. 7. ]
[ 8. 9. 10. 11. ]]
>>> print(arr_out_nonsquare.shape)
(3, 4)
"""
assert arr_in.ndim == 3
n_images, height, width = arr_in.shape
arr_in = arr_in.copy()
# -- rescale intensity if necessary
if rescale_intensity:
for i in range(n_images):
arr_in[i] = exposure.rescale_intensity(arr_in[i])
# -- determine alpha
if grid_shape:
alpha_y, alpha_x = grid_shape
else:
alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images)))
# -- fill missing patches
if fill == 'mean':
fill = arr_in.mean()
n_missing = int((alpha_y * alpha_x) - n_images)
missing = np.ones((n_missing, height, width), dtype=arr_in.dtype) * fill
arr_out = np.vstack((arr_in, missing))
# -- reshape to 2d montage, step by step
arr_out = arr_out.reshape(alpha_y, alpha_x, height, width)
arr_out = arr_out.swapaxes(1, 2)
arr_out = arr_out.reshape(alpha_y * height, alpha_x * width)
return arr_out