简体   繁体   中英

Interpolation of numpy array with a maximum interpolation distance

I have a numpy array that looks like this. 原始数据

I want to interpolate between data points to fill some smaller holes in the data. Let's say in this example I want to interpolate over a maximum of 2 pixels. Then I would expect something similar to this. 预期结果

So far I've tried several interpolation methods like:

from scipy.interpolate import LinearNDInterpolator
valid_mask = ~np.isnan(raw)
coords = np.array(np.nonzero(valid_mask)).T
values = raw[valid_mask]
it = LinearNDInterpolator(coords, values)
interpolated = it(list(np.ndindex(raw.shape))).reshape(raw.shape)

which lead to the result. 插补

This approach doesn't preserve clusters in the data, which I could easyly overcome by clustering beforehand and then adding the results. But more importantly it interpolates over high distances in clusters that have a concave form.

Could anyone point out to me an interpolation method that used some kind of distance threshold?

For testing I included the sample data that I used to explain my problem:

raw = np.array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  1.,  0.,  0.,  3.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  5.,  4.,  4.,  4.,  4.,  4.,  5.],
   [ 0.,  5.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

raw[raw==0]=np.nan

You could do a binary_closing (for example, from skimage.morphology or scipy.ndimage.morphology ) to mask your final output.

from skimage import morphology
close_mask = morphology.binary_closing(valid_mask, morphology.square(3))
interpolated[:] = np.where(close_mask, interpolated, np.nan)

Results in:

array([[    nan,     nan,     nan,     nan,     nan,     nan,     nan,     nan],
       [    nan,  1.    ,  1.6667,  2.3333,  3.    ,     nan,     nan,     nan],
       [    nan,     nan,     nan,     nan,     nan,     nan,     nan,     nan],
       [    nan,     nan,     nan,     nan,     nan,     nan,     nan,     nan],
       [    nan,     nan,     nan,     nan,     nan,     nan,     nan,     nan],
       [    nan,  5.    ,  4.    ,  4.    ,  4.    , 4.     ,  4.    ,     nan],
       [    nan,  5.    ,  3.    ,     nan,     nan,     nan,     nan,     nan],
       [    nan,     nan,  2.    ,     nan,     nan,     nan,     nan,     nan],
       [    nan,     nan,  1.    ,     nan,     nan,     nan,     nan,     nan],
       [    nan,     nan,     nan,     nan,     nan,     nan,     nan,     nan]])

Change the kernel size and shape to get exactly what you want; several are available or you can make your own. Obviously this is not super efficient, because it does the entire interpolation but only keeps the parts you want. I'm not sure how to limit where the calculation is done in the first place.

Also, it seems to kill the boundary (see row 5). I imagine this can be fixed.

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