Upsample and Interpolate a NumPy Array

28,207

Solution 1

You can use SciPy interp2d for the interpolation, you can find the documentation here.

I've modified the example from the documentation a bit:

from scipy import interpolate
x = np.array(range(2))
y = np.array(range(2))
a = np.array([[0, 1], [2, 3]])
f = interpolate.interp2d(x, y, a, kind='linear')

xnew = np.linspace(0, 2, 4)
ynew = np.linspace(0, 2, 4)
znew = f(xnew, ynew)

If you print znew it should look like this:

array([[ 0.        ,  0.66666667,  1.        ,  1.        ],
       [ 1.33333333,  2.        ,  2.33333333,  2.33333333],
       [ 2.        ,  2.66666667,  3.        ,  3.        ],
       [ 2.        ,  2.66666667,  3.        ,  3.        ]])

Solution 2

I would use scipy.misc.imresize:

array = np.arange(0,4,1).reshape(2,2)
from skimage.transform import resize
out = scipy.misc.imresize(array, 2.0)

The 2.0 indicates that I want the output to be twice the dimensions of the input. You could alternatively supply an int or a tuple to specify a percentage of the original dimensions or just the new dimensions themselves.

This is very easy to use, but there is an extra step because imresize rescales everything so that your max value becomes 255 and your min becomes 0. (And it changes the datatype to np.unit8.) You may need to do something like:

out = out.astype(array.dtype) / 255 * (np.max(array) - np.min(array)) + np.min(array)

Let's look at the output:

>>> out.round(2)
array([[0.  , 0.25, 0.75, 1.  ],
       [0.51, 0.75, 1.26, 1.51],
       [1.51, 1.75, 2.26, 2.51],
       [2.  , 2.25, 2.75, 3.  ]])

imresize comes with a deprecation warning and a substitute, though:

DeprecationWarning: imresize is deprecated! imresize is deprecated in SciPy 1.0.0, and will be removed in 1.2.0. Use skimage.transform.resize instead.

Share:
28,207
tda
Author by

tda

Updated on May 04, 2022

Comments

  • tda
    tda about 2 years

    I have an array, something like:

    array = np.arange(0,4,1).reshape(2,2)
    
    > [[0 1
        2 3]]
    

    I want to both upsample this array as well as interpolate the resulting values. I know that a good way to upsample an array is by using:

    array = eratemp[0].repeat(2, axis = 0).repeat(2, axis = 1)
    [[0 0 1 1]
     [0 0 1 1]
     [2 2 3 3]
     [2 2 3 3]]
    

    but I cannot figure out a way to interpolate the values to remove the 'blocky' nature between each 2x2 section of the array.

    I want something like this:

    [[0 0.4 1 1.1]
     [1 0.8 1 2.1]
     [2 2.3 3 3.1]
     [2.1 2.3 3.1 3.2]]
    

    Something like this (NOTE: these will not be the exact numbers). I understand that it may not be possible to interpolate this particular 2D grid, but using the first grid in my answer, an interpolation should be possible during the upsampling process as you are increasing the number of pixels, and can therefore 'fill in the gaps'.

    I am not too fussed on the type of interpolation, providing the final output is a smoothed surface! I have tried to use the scipy.interp2d method but to no avail, would be grateful if someone could share their wisdom!

    • tnknepp
      tnknepp over 7 years
      Are you wanting to do a two-dimensional interpolation? I do not see how this would work. As you as you interpolate one axis you would break the interpolation of the other. Right?
    • Ahmed Fasih
      Ahmed Fasih over 7 years
      “you get the idea!” — sorry, I don’t quite get it. Could you fill out the rest of the 4x4 array that you’re expecting?
    • tda
      tda over 7 years
      Thanks for you comments. I have filled in the rest of the grid to give some idea of my desired result. I understand that interpolating the second 2D grid in my answer may be problematic, but there must be a way to interpolate the the first grid whilst the upsampling process is happening?
  • tda
    tda over 7 years
    +1 Thankyou! Good use of an existing function to do both my upsampling and interpolation steps in one go!
  • Admin
    Admin over 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.