简体   繁体   中英

How to resize an arbitrary Numpy NDArray to a new shape with interpolation

Remark:

This is rather a contribution than a question since I will answer my own question. However, I am still interested in how the community would solve this problem. So feel free to answer.


Story:

So when I was playing around with QT in Python (ie, PySide6) and it's Volumerendering capabilities I noticed some problems when setting my data array. Long story short: I didn't know (and if it is stated somwhere in the QT documentation at all) that the provided texture has to be of a shape where each dimension is a power of two.

Thus, I wanted to rescale my array to a shape which fulfills this criteria.

Calculating this shape with numpy is easy:
new_shape = numpy.power(2, numpy.ceil(numpy.log2(old_shape))).astype(int)

Now the only problem left is to rescale my array with shape old_shape to the new array with shape new_shape and properly interpolate the values.

And since I am usually only interested in some sort of generic approaches (who knows what this might be good for and for whom in the future), the following question did arise:

Question

How to resize an arbitrary Numpy NDArray of shape old_shape to a Numpy NDArray of shape new shape with proper interpolation?

I tried using scipy RegularGridInterpolator to rescale my array and it actually worked.

I used scipy's RegularGridInterpolator to interpolate my array.

Other interpolators should work as well.

def resample_array_to_shape(array: np.array, new_shape, method="linear"):
    # generate points for each entry in the array
    entries = [np.arange(s) for s in array.shape]

    # the value for each point corresponds to its value in the original array
    interp = RegularGridInterpolator(entries, array, method=method)

    # new entries
    new_entries = [np.linspace(0, array.shape[i] - 1, new_shape[i]) for i in range(len(array.shape))]
    
    # use 'ij' indexing to avoid swapping axes
    new_grid = np.meshgrid(*new_entries, indexing='ij')

    # interpolate and return
    return interp(tuple(new_grid)).astype(array.dtype)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM