From 49967b412ba78e4512950fad5c69bc464b7d9a60 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 14 Jun 2015 17:39:25 -0500 Subject: [PATCH 1/2] Create an optimal step parameter for view_as_windows --- skimage/util/shape.py | 14 +++++++++++++- skimage/util/tests/test_shape.py | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/skimage/util/shape.py b/skimage/util/shape.py index 78bb7bb9..505ba9cd 100644 --- a/skimage/util/shape.py +++ b/skimage/util/shape.py @@ -103,7 +103,7 @@ def view_as_blocks(arr_in, block_shape): return arr_out -def view_as_windows(arr_in, window_shape, step=1): +def view_as_windows(arr_in, window_shape, step=1, optimal_step=False): """Rolling window view of the input n-dimensional array. Windows are overlapping views of the input array, with adjacent windows @@ -121,6 +121,9 @@ def view_as_windows(arr_in, window_shape, step=1): step : integer or tuple of length arr_in.ndim Indicates step size at which extraction shall be performed. If integer is given, then the step is uniform in all dimensions. + optimal_step: bool, optional + When True, selects a ``step`` that will give full coverage of + ``arr_in`` with minimal overlap. Returns ------- @@ -225,6 +228,15 @@ def view_as_windows(arr_in, window_shape, step=1): if not (len(window_shape) == ndim): raise ValueError("`window_shape` is incompatible with `arr_in.shape`") + if optimal_step: + rem = np.array(arr_in.shape) - np.array(window_shape) + step = list(window_shape) + + for (ind, size) in enumerate(window_shape): + ns = int(np.ceil(arr_in.shape[ind] / size)) + while step[ind] * (ns - 1) > rem[ind]: + step[ind] -= 1 + if isinstance(step, numbers.Number): if step < 1: raise ValueError("`step` must be >= 1") diff --git a/skimage/util/tests/test_shape.py b/skimage/util/tests/test_shape.py index 7a6a785d..5c59edb0 100644 --- a/skimage/util/tests/test_shape.py +++ b/skimage/util/tests/test_shape.py @@ -176,5 +176,21 @@ def test_view_as_windows_step_tuple(): [22, 23]]]]) +def test_view_as_windows_optimal_step(): + A = np.arange(24).reshape((6, 4)) + B = view_as_windows(A, (3, 2), optimal_step=True) + assert B.shape == (2, 2, 3, 2) + assert B.size == A.size + + A = np.arange(512 * 512).reshape((512, 512)) + B = view_as_windows(A, (10, 10), optimal_step=True) + assert B.shape == (56, 56, 10, 10) + assert B.size >= A.size + + C = view_as_windows(A, (11, 9), optimal_step=True) + assert C.shape == (51, 63, 11, 9) + assert C.size >= A.size + + if __name__ == '__main__': np.testing.run_module_suite() From 0ffe44a4f0095b3e6fe0ad4450db44d06c2841a6 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Sun, 14 Jun 2015 20:19:13 -0500 Subject: [PATCH 2/2] Ensure consistent handling of division --- skimage/util/shape.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/util/shape.py b/skimage/util/shape.py index 505ba9cd..48e9a5ef 100644 --- a/skimage/util/shape.py +++ b/skimage/util/shape.py @@ -1,3 +1,4 @@ +from __future__ import division import numbers import numpy as np from numpy.lib.stride_tricks import as_strided