首页 > 解决方案 > Scikit-image:如何忽略/屏蔽 ndarray 中的零值以便之后进行插值?

问题描述

正如您在上面看到的我的问题,我想屏蔽/忽略 ndarray 中的零值,然后我想对其进行插值。我希望你能帮我解决这个问题,因为我已经尝试了很多天来解决这个问题。

我想要什么?

我有许多长度大小不同的 ndarray,我想对其进行插值,比如说在这种情况下,以使其更小。

这就是这些数组之一的样子:

[0.0, 0.0, 0.0, 0.0, 0.0, 144.0, 144.0, 145.0, 145.0, 144.0, 143.0, 143.0, 0.0, 0.0, 0.0]

正如你所看到的,它总是一行(我们称之为“array_row”),有很多元素(对于这个例子,我刚刚写了一个包含 15 个元素的数组示例)

我该如何插值?

我正在使用 scikit-image 调整大小的方法,如下所示:

new_array = skimage.transform.resize(array_row, (1, 10))

此插值的结果如下所示:

[0.0, 0.0, 71.49999999, 144.0, 144.60344827, 145.0, 144.70896278, 143.0, 71.49999999, 0.0, 0.0]

使用插值时,这个结果是这样的。值“71.49999999”是因为非零值之前和/或之后的零值,这是正常的。

但就我而言,我不希望这种情况发生。我想让skimage.transform.resize忽略零值,以便结果如下所示:

[0.0, 0.0, 144.0, 144.0, 144.60344827, 145.0, 144.70896278, 143.0, 143.0, 0.0, 0.0]

这些值不应更改(或至少仅从其旁边的非零值更改)。

我实际上不知道该怎么做。我尝试了一些类似屏蔽的方法,并将屏蔽索引的值设为“255”,这也没有给出预期的结果。

您对如何实现这一目标有任何想法吗?

标签: pythonpython-3.xscikit-image

解决方案


scikit-image 函数需要一个规则间隔的值网格,但是 scipy 中还有其他插值器允许更多的自由度。例如,考虑一个三次插值器,它将输入坐标和值作为输入:

import numpy as np
from scipy import interpolate

import matplotlib.pyplot as plt


y = np.array([150, 0.0, 0.0, 0.0, 0.0, 144.0, 144.0, 145.0, 145.0, 144.0, 143.0, 143.0, 0.0, 0.0, 148])
x = np.arange(len(y))
x_ = np.linspace(0, 14, 100)
mask = (y != 0)

p = interpolate.interp1d(x, y, kind='cubic')
p_masked = interpolate.interp1d(x[mask], y[mask], kind='cubic')

plt.plot(x, y, 'x-', label='Input')
plt.plot(x_, p(x_), label='Interpolated')
plt.plot(x_, p_masked(x_), label='Interpolated (ignoring zeros)')
plt.legend()
plt.savefig('/tmp/cubic_interpolation.png', dpi=300)
plt.show()

有和没有掩蔽的三次插值

对于这种方法,您需要指定端点,因为它不会外推。径向基函数更适用于外推,但在没有数据的区域也会趋于回落到零。


推荐阅读