From 45d960d64f765dcf1ace17fe6c5baf052c32656f Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Thu, 27 Jun 2013 08:15:49 +0200 Subject: [PATCH 01/12] User-specified output ratio Added a keyword argument which enables the user to select other ratios for the output image rather than just 1:1. --- skimage/util/montage.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index df3ad12e..4d7deb9d 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -1,12 +1,12 @@ __all__ = ['montage2d'] import numpy as np -from .. import exposure +#~ from .. import exposure EPSILON = 1e-6 -def montage2d(arr_in, fill='mean', rescale_intensity=False): +def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0,0)): """Create a 2-dimensional 'montage' from a 3-dimensional input array representing an ensemble of equally shaped 2-dimensional images. @@ -38,6 +38,9 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False): rescale_intensity: bool, optional Whether to rescale the intensity of each image to [0, 1]. + + output_shape: tuple, optional + The desired aspect ratio for the montage (default is square). Returns ------- @@ -80,19 +83,23 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False): arr_in[i] = exposure.rescale_intensity(arr_in[i]) # -- determine alpha - alpha = int(np.ceil(np.sqrt(n_images))) + if output_shape == (0,0): + alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) + else: + alpha_y = output_shape[0] + alpha_x = output_shape[1] # -- fill missing patches if fill == 'mean': fill = arr_in.mean() - n_missing = int((alpha**2.) - n_images) + 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, alpha, height, width) + arr_out = arr_out.reshape(alpha_y, alpha_x, height, width) arr_out = arr_out.swapaxes(1, 2) - arr_out = arr_out.reshape(alpha * height, alpha * width) + arr_out = arr_out.reshape(alpha_y * height, alpha_x * width) return arr_out From 8367542a20b405a17acaeaf4cbdf911102616731 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Fri, 28 Jun 2013 01:25:13 +0200 Subject: [PATCH 02/12] Corrected indentation and spacing. --- skimage/util/montage.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index 4d7deb9d..74f65741 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -1,12 +1,12 @@ __all__ = ['montage2d'] import numpy as np -#~ from .. import exposure +from .. import exposure EPSILON = 1e-6 -def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0,0)): +def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)): """Create a 2-dimensional 'montage' from a 3-dimensional input array representing an ensemble of equally shaped 2-dimensional images. @@ -33,11 +33,11 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0,0)): 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(). + 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]. + Whether to rescale the intensity of each image to [0, 1]. output_shape: tuple, optional The desired aspect ratio for the montage (default is square). @@ -83,7 +83,7 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0,0)): arr_in[i] = exposure.rescale_intensity(arr_in[i]) # -- determine alpha - if output_shape == (0,0): + if output_shape == (0, 0): alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) else: alpha_y = output_shape[0] From 03623a30280c06f1915391fee0235b14ba56b548 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Fri, 28 Jun 2013 05:28:15 +0200 Subject: [PATCH 03/12] Corrected indents (4space instead tab). --- skimage/util/montage.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index 74f65741..bf6ab06c 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -33,14 +33,14 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) 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(). + 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]. + Whether to rescale the intensity of each image to [0, 1]. output_shape: tuple, optional - The desired aspect ratio for the montage (default is square). + The desired aspect ratio for the montage (default is square). Returns ------- @@ -84,10 +84,10 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) # -- determine alpha if output_shape == (0, 0): - alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) + alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) else: - alpha_y = output_shape[0] - alpha_x = output_shape[1] + alpha_y = output_shape[0] + alpha_x = output_shape[1] # -- fill missing patches if fill == 'mean': From 9e415a096a9ae2d80111295a6a20db15b55bd4f5 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Fri, 28 Jun 2013 13:21:55 +0200 Subject: [PATCH 04/12] Corrected indents Again. --- skimage/util/montage.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index bf6ab06c..b5410b82 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -33,14 +33,14 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) 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(). + 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]. - + Whether to rescale the intensity of each image to [0, 1]. + output_shape: tuple, optional - The desired aspect ratio for the montage (default is square). + The desired aspect ratio for the montage (default is square). Returns ------- @@ -84,10 +84,10 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) # -- determine alpha if output_shape == (0, 0): - alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) + alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) else: - alpha_y = output_shape[0] - alpha_x = output_shape[1] + alpha_y = output_shape[0] + alpha_x = output_shape[1] # -- fill missing patches if fill == 'mean': From 9583072271ae5740f66b56dd392c525b2bb5bee8 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Fri, 28 Jun 2013 20:20:39 +0200 Subject: [PATCH 05/12] Added usage example. --- skimage/util/montage.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index b5410b82..03e2808a 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -70,6 +70,13 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) [ 10. 11. 5.5 5.5]] >>> print(arr_in.mean()) 5.5 + >>> arr_out_nonsquare = montage2d(arr_in, output_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 From 633dca7c9748686306f4b6a67c703846217985ba Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Tue, 9 Jul 2013 00:28:57 +0200 Subject: [PATCH 06/12] Refined syntax. --- skimage/util/montage.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index 03e2808a..ff7793d6 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -93,14 +93,13 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) if output_shape == (0, 0): alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) else: - alpha_y = output_shape[0] - alpha_x = output_shape[1] + alpha_y, alpha_x = output_shape # -- fill missing patches if fill == 'mean': fill = arr_in.mean() - n_missing = int((alpha_y*alpha_x) - n_images) + 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)) From 70aedc4556a5684708ae43e3f2d25a377e76c97d Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Wed, 10 Jul 2013 22:18:09 +0200 Subject: [PATCH 07/12] Removed blank lines in between parameters. --- skimage/util/montage.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index ff7793d6..b9d8defa 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -31,14 +31,11 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) 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]. - output_shape: tuple, optional The desired aspect ratio for the montage (default is square). @@ -99,7 +96,7 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) if fill == 'mean': fill = arr_in.mean() - n_missing = int((alpha_y * alpha_x) - n_images) + 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)) From 1c7947fad1e5608d47f1a46ff8bf6da3275c0226 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Sun, 14 Jul 2013 22:21:51 +0200 Subject: [PATCH 08/12] Renamed parameter --- skimage/util/montage.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index b9d8defa..f75af3b7 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -6,7 +6,7 @@ from .. import exposure EPSILON = 1e-6 -def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)): +def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=(0, 0)): """Create a 2-dimensional 'montage' from a 3-dimensional input array representing an ensemble of equally shaped 2-dimensional images. @@ -36,8 +36,8 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) 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]. - output_shape: tuple, optional - The desired aspect ratio for the montage (default is square). + grid_shape: tuple, optional + The desired grid shape for the montage (the default aspect ratio is square). Returns ------- @@ -67,7 +67,7 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) [ 10. 11. 5.5 5.5]] >>> print(arr_in.mean()) 5.5 - >>> arr_out_nonsquare = montage2d(arr_in, output_shape = (3, 4)) + >>> arr_out_nonsquare = montage2d(arr_in, grid_shape = (3, 4)) >>> print(arr_out_nonsquare) [[ 0. 1. 4. 5. ] [ 2. 3. 6. 7. ] @@ -87,10 +87,10 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, output_shape=(0, 0)) arr_in[i] = exposure.rescale_intensity(arr_in[i]) # -- determine alpha - if output_shape == (0, 0): + if grid_shape == (0, 0): alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) else: - alpha_y, alpha_x = output_shape + alpha_y, alpha_x = grid_shape # -- fill missing patches if fill == 'mean': From 90f3a5d6851afdc2c64f19379f50986d33d70968 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Thu, 18 Jul 2013 17:54:03 +0200 Subject: [PATCH 09/12] Syntax and default variable. From (0,0) to None. --- skimage/util/montage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index f75af3b7..cd87a078 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -6,7 +6,7 @@ from .. import exposure EPSILON = 1e-6 -def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=(0, 0)): +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. @@ -37,7 +37,7 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=(0, 0)): 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 (the default aspect ratio is square). + The desired grid shape for the montage (tiles_y, tiles_x). Tthe default aspect ratio is square. Returns ------- @@ -67,7 +67,7 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=(0, 0)): [ 10. 11. 5.5 5.5]] >>> print(arr_in.mean()) 5.5 - >>> arr_out_nonsquare = montage2d(arr_in, grid_shape = (3, 4)) + >>> arr_out_nonsquare = montage2d(arr_in, grid_shape=(3, 4)) >>> print(arr_out_nonsquare) [[ 0. 1. 4. 5. ] [ 2. 3. 6. 7. ] From 228bf8f7ba633dc39bf76e864206502098d3d3c1 Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Fri, 19 Jul 2013 00:32:38 +0200 Subject: [PATCH 10/12] Adapted if statement to grid_shape=None --- skimage/util/montage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skimage/util/montage.py b/skimage/util/montage.py index cd87a078..bdafe6ed 100644 --- a/skimage/util/montage.py +++ b/skimage/util/montage.py @@ -87,10 +87,10 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=None): arr_in[i] = exposure.rescale_intensity(arr_in[i]) # -- determine alpha - if grid_shape == (0, 0): - alpha_y = alpha_x = int(np.ceil(np.sqrt(n_images))) - else: + 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': From 2d33bf7622ca1f5ed5cebdfaf7f27919ffbf850d Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Sun, 21 Jul 2013 03:55:16 +0200 Subject: [PATCH 11/12] Added test case for grid_shape parameter. --- skimage/util/tests/test_montage.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/skimage/util/tests/test_montage.py b/skimage/util/tests/test_montage.py index 47e5426d..9de3f3cd 100644 --- a/skimage/util/tests/test_montage.py +++ b/skimage/util/tests/test_montage.py @@ -51,6 +51,23 @@ def test_shape(): arr_out = montage2d(arr_in) assert_equal(arr_out.shape, (alpha * height, alpha * width)) + + +def test_grid_shape(): + n_images = 6 + height, width = 2, 2 + arr_in = np.arange(n_images * height * width, dtype=np.float32) + arr_in = arr_in.reshape(n_images, height, width) + arr_out = montage.montage2d(arr_in, grid_shape=(3,2)) + correct_arr_out = np.array( + [[ 0., 1., 4., 5.], + [ 2., 3., 6., 7.], + [ 8., 9., 12., 13.], + [ 10., 11., 14., 15.], + [ 16., 17., 20., 21.], + [ 18., 19., 22., 23.]] + ) + assert_array_equal(arr_out, correct_arr_out) def test_rescale_intensity(): From 35a65aeef34192b644c9a3afaa13060dee3be0ad Mon Sep 17 00:00:00 2001 From: Horea Christian Date: Sun, 21 Jul 2013 05:55:02 +0200 Subject: [PATCH 12/12] Resolved faulty montage2d import. --- skimage/util/tests/test_montage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/util/tests/test_montage.py b/skimage/util/tests/test_montage.py index 9de3f3cd..450ab0d2 100644 --- a/skimage/util/tests/test_montage.py +++ b/skimage/util/tests/test_montage.py @@ -58,7 +58,7 @@ def test_grid_shape(): height, width = 2, 2 arr_in = np.arange(n_images * height * width, dtype=np.float32) arr_in = arr_in.reshape(n_images, height, width) - arr_out = montage.montage2d(arr_in, grid_shape=(3,2)) + arr_out = montage2d(arr_in, grid_shape=(3,2)) correct_arr_out = np.array( [[ 0., 1., 4., 5.], [ 2., 3., 6., 7.],