Slicing a numpy image array into blocks Slicing a numpy image array into blocks numpy numpy

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]]