Skip to content Skip to sidebar Skip to footer

Interpolation Of Values When Zooming Down

I have a 2D array that I would like to down sample to compare it to another. Lets say my array x is 512x512, I'd like an array y 128x128 where the elements of y are build using an

Solution 1:

sklearn.feature_extraction.image.extract_patches cleverly uses np.lib.stride_tricks.as_strided to produce a windowed array that can be operated on.

The sliding_window function, found here Efficient Overlapping Windows with Numpy, produces a windowed array with or without overlap also and let's you get a glimpse of what is happening under the hood.

>>>a = np.arange(16).reshape(4,4)

step_height,step_width determines the overlap for the windows - in your case the steps are the same as the window size, no overlap.

>>> window_height, window_width, step_height, step_width = 2, 2, 2, 2
>>> y = sliding_window(a, (window_height, window_width), (step_height,step_width))
>>> y
array([[[ 0,  1],
        [ 4,  5]],

       [[ 2,  3],
        [ 6,  7]],

       [[ 8,  9],
        [12, 13]],

       [[10, 11],
        [14, 15]]])

Operate on the windows:

>>>y = y.mean(axis = (1,2))>>>y
array([  2.5,   4.5,  10.5,  12.5])

You need to determine the final shape depending on the number of windows.

>>>final_shape = (2,2)>>>y = y.reshape(final_shape)>>>y
array([[  2.5,   4.5],
       [ 10.5,  12.5]])

Searching SO for numpy, window, array should produce numerous other answers and possible solutions.

Solution 2:

What you seem to be looking for is the mean over blocks of 4, which is not obtainable with zoom, since zoom uses interpolation (see its docstring)

To obtain what you show, try the following

import numpy as np
x = np.arange(16).reshape(4, 4)

xx = x.reshape(len(x) // 2, 2, x.shape[1] // 2, 2).transpose(0, 2, 1, 3).reshape(len(x) // 2, x.shape[1] // 2, -1).mean(-1)

print xx

This yields

[[  2.5   4.5]
 [ 10.5  12.5]]

Alternatively, this can be done using sklearn.feature_extraction.image.extract_patches

from sklearn.feature_extraction.image import extract_patches

patches = extract_patches(x, patch_shape=(2, 2), extraction_step=(2, 2))

xx = patches.mean(-1).mean(-1)

print xx

However, if your goal is to subsample an image in a graceful way, then taking the mean over blocks of the image is not the right way to do it: It is likely to cause aliasing effects. What you should do in this case is smooth the image ever so slightly using scipy.ndimage.gaussian_filter (e.g. sigma=0.35 * subsample_factor) and then subsample simply by indexing [::2, ::2]

Post a Comment for "Interpolation Of Values When Zooming Down"