Slicing a numpy image array into blocks
The scikit image extract_patches_2d does that
>>> from sklearn.feature_extraction import image>>> one_image = np.arange(16).reshape((4, 4))>>> one_imagearray([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]])>>> patches = image.extract_patches_2d(one_image, (2, 2))>>> print(patches.shape)(9, 2, 2)>>> patches[0]array([[0, 1], [4, 5]])>>> patches[1]array([[1, 2], [5, 6]])>>> patches[8]array([[10, 11], [14, 15]])
You can use something like this:
def rolling_window(arr, window): """Very basic multi dimensional rolling window. window should be the shape of of the desired subarrays. Window is either a scalar or a tuple of same size as `arr.shape`. """ shape = np.array(arr.shape*2) strides = np.array(arr.strides*2) window = np.asarray(window) shape[arr.ndim:] = window # new dimensions size shape[:arr.ndim] -= window - 1 if np.any(shape < 1): raise ValueError('window size is too large') return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)# Now:slices = rolling_window(arr, 2)# Slices will be 4-d not 3-d as you wanted. You can reshape# but it may need to copy (not if you have done no slicing, etc. with the array):slices = slices.reshape(-1,slices.shape[2:])
Simple code with a double loop and slice:
>>> a = np.arange(12).reshape(3,4)>>> print(a)[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]]>>> r = 2>>> n_rows, n_cols = a.shape>>> for row in range(n_rows - r + 1):... for col in range(n_cols - r + 1):... print(a[row:row + r, col:col + r])...[[0 1] [4 5]][[1 2] [5 6]][[2 3] [6 7]][[4 5] [8 9]][[ 5 6] [ 9 10]][[ 6 7] [10 11]]