NumPy修复缺失值,插值和外推。

4
我正在使用numpy和scipy做一个项目,需要填充nan值。目前我使用scipy.interpolate.rbf,但它会导致python崩溃得如此严重,即使try/except也无法保存。然而,运行几次后,似乎在周围全部是nan的情况下中间有数据时可能会不断失败,就像一个孤岛一样。有没有更好的解决方案可以避免这种频繁崩溃?
顺便说一句,我需要外推的数据量很大。有时候甚至达到了图像的一半(70x70,灰度),但它并不需要完美。它是图像拼接程序的一部分,只要与实际数据相似,就能工作。我尝试过最近邻来填充nans,但结果太不同了。
编辑:
总是似乎在失败的图像上。将该图像隔离出来后,它才能通过一次图像再次崩溃。 Bad Image 我至少使用的是NumPy 1.8.0和SciPy 0.13.2版本。

2
你能否提供一个小例子来展示这个失败吗? - perimosocordiae
你正在使用哪个版本的scipy? - Warren Weckesser
我已经更新了我的问题,附上了一张图片和版本信息。 - wbest
2个回答

7
使用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


这并没有完全解决我的问题(虽然部分原因是我没有包含一张图片),因为我需要进行更多的外推而不是内插。但预先计算网格坐标是个好主意。 - wbest
一个正确的外推看起来会是什么样子?为什么不直接镜像图像?基本上,任何外推都是在给定图像之外"有效"的。 - Stefan van der Walt
1
最近邻居方法可能不错,但这种方法会产生我不想要的条纹。我现在想到了一种能够产生合理结果的方法,即在边缘处填充所有方块的nanmean,然后使用griddata进行线性插值。 - wbest

4
这对我的需求来说已经足够了。它实际上非常快速,并且产生的结果也还不错:
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

1
这似乎类似于OpenCV中的一种修复方法(INPAINT_TELEA):https://docs.opencv.org/3.4.0/df/d3d/tutorial_py_inpainting.html - moi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接