2014-02-11 146 views
3

我正在使用numpy和scipy進行項目,我需要填寫nanvalues。目前我使用scipy.interpolate.rbf,但它不斷導致python崩潰如此嚴重的嘗試/除非不保存它。然而,在運行幾次之後,似乎在中間數據被所有nans包圍的情況下(如島嶼)可能會失敗。有沒有更好的解決方案,這將不會崩潰?Numpy inpaint nans內插和外插

順便說一下,這是我需要外推的大量數據。有時多達一半的圖像(70x70,灰度),但它並不需要完美。它是圖像拼接程序的一部分,只要它與實際數據相似,它就可以工作。我已經嘗試過最近的鄰居來填寫nans,但結果太不同了。

編輯

的形象似乎總是失敗的。隔離這個圖像允許它在崩潰前傳遞圖像一次。 Bad Image

我至少使用了版本NumPy 1.8.0和SciPy 0.13.2。

+2

你能發表一個小的例子,展示失敗? – perimosocordiae

+0

你使用的是什麼版本的scipy? –

+0

我已經用圖像和版本更新了我的問題。 – wbest

回答

3

使用SciPy的LinearNDInterpolator。如果所有圖像的大小相同,則網格座標可以預先計算並重新使用。

import numpy as np 
import matplotlib.pyplot as plt 
from scipy import interpolate 

x = np.linspace(0, 1, 500) 
y = x[:, None] 
image = x + y 

# Destroy some values 
mask = np.random.random(image.shape) > 0.7 
image[mask] = np.nan 

valid_mask = ~np.isnan(image) 
coords = np.array(np.nonzero(valid_mask)).T 
values = image[valid_mask] 

it = interpolate.LinearNDInterpolator(coords, values, fill_value=0) 

filled = it(list(np.ndindex(image.shape))).reshape(image.shape) 

f, (ax0, ax1) = plt.subplots(1, 2) 

ax0.imshow(image, cmap='gray', interpolation='nearest') 
ax0.set_title('Input image') 
ax1.imshow(filled, cmap='gray', interpolation='nearest') 
ax1.set_title('Interpolated data') 
plt.show() 

Interpolated missing values

+0

這並不能很好地解決我的問題(儘管它不包括圖像的一部分是我的錯),因爲我需要做比內插更多的外推。但是預先計算網格座標是一個很好的調用。 – wbest

+0

正確的外推是什麼樣的?爲什麼不簡單地鏡像圖像?幾乎任何外推法都是在給定圖像之外「有效」的。 –

+1

最近鄰居的方法會很好,除非該方法導致我不想要的條紋。我想我實際上有一種方法現在可以生成合理的結果,其中我用所有方塊的納米量填充邊緣,然後使用網格數據線性插入。 – wbest

2

這證明足以滿足我的需求。它實際上相當快,併產生合理的結果:

ipn_kernel = np.array([[1,1,1],[1,0,1],[1,1,1]]) # kernel for inpaint_nans 

def inpaint_nans(im): 
    nans = np.isnan(im) 
    while np.sum(nans)>0: 
     im[nans] = 0 
     vNeighbors = scipy.signal.convolve2d((nans==False),ipn_kernel,mode='same',boundary='symm') 
     im2 = scipy.signal.convolve2d(im,ipn_kernel,mode='same',boundary='symm') 
     im2[vNeighbors>0] = im2[vNeighbors>0]/vNeighbors[vNeighbors>0] 
     im2[vNeighbors==0] = np.nan 
     im2[(nans==False)] = im[(nans==False)] 
     im = im2 
     nans = np.isnan(im) 
    return im