使用NumPy进行快速插值

4
给定一个掩码NumPy数组,维度为(frames,points,2),表示跟踪frames帧的每个帧中points(x,y)点的视频。
我想将这个视频从frames帧插值到任意数量的帧数中,速度非常快,希望能使用三次样条插值,但是任何其他连续插值也可以工作。
我实现的朴素解决方案将数组分成维度为(frames,points)的两个数组XY
然后,我将数组转置为(points,frames)。对于每一行(单点随时间变化),我将其映射到索引和值,因此数组[5,6, - ,7]变为: [{"x": 0, "y": 5}, {"x": 1, "y": 6}, {"x": 3, "y": 7}] 我将其提供给scipy.interp1d,并运行在我的新数组上,例如[0,0.5,1,1.5,2,2.5,3],然后得到一个新的x,y数组,然后将其转换回NumPy。
此过程会删除间歇帧的掩码(这对我来说没问题)。
当前性能:形状小数组(9帧,140个点,2)(24帧,140个点,2)
  • 立方插值 0.115秒
  • 线性插值 0.112秒

注意!

这是一个掩码数组,例如[5,6, - ,7]。因此,重要的是在插值中合并掩码,以便不会有0值(数据数组看起来像[5,6,0,7]!)
以下是具有所需和不需要行为数据的玩具示例:
import numpy as np
import numpy.ma as ma
from scipy.interpolate import interp1d

points = np.array([1, 2, 3, 4, 0, 6])
mask = [0, 0, 0, 0, 1, 0]
points = ma.array(points, mask=mask)
print(points)  # [1 2 3 4 -- 6]

lin = np.linspace(0, 1, 6)

# Undesired behavior
f = interp1d(lin, points, axis=0, kind='cubic')
print(f(lin))  # [1  2 3 4 -8.8817842e-16 6]

# Desired behavior
compressed_lin = [0, 0.2, 0.4, 0.6, 1]
compressed_points = np.array([1,2,3,4,6])
f = interp1d(compressed_lin, compressed_points, axis=0, kind='cubic')
print(f(lin)) # [1 2 3 4 5 6]

当你从9帧转换到24帧时,这些帧是均匀分布的,还是它们有自己的帧时间戳? - Quang Hoang
我的插值帧总是均匀间隔的。 - Amit
还适用于 9 帧吗? - Quang Hoang
是的,如果你有9个帧,它们会在[0,0.125,0.250,0.375,0.500,0.625,0.750,0.875,1]间隔,并且如果我们需要插值至25帧,则会尝试插值这些值:[0, 0.04, 0.08, ... , 0.92, 0.92, 1] (这是一个示例,其中的值介于0和1之间,但它们也可以介于0和9之间,无所谓) - Amit
2个回答

2

我不确定你是否像我一样使用scipy.interpolate.interp1d,但我的电脑显示大约662 µs

np.random.seed(1)
points = np.random.rand(9,140,2)

f = interp1d(np.linspace(0,1,9), points, axis=0, kind='cubic')
f(np.linspace(0,1,24))

性能测试(timeit -n 100):

662 µs ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

谢谢。可能是周围事物的积累导致了这种情况。例如,我不知道可以按照您展示的方式进行操作,而是逐行进行操作。我之所以这样做是因为我有一个掩码数组,而不是完整的numpy数组。就像我的例子一样,有时我想跳过一些索引。您知道是否有办法将这个事实纳入到您的解决方案中吗? - Amit

1
如果您需要快速处理,1)避免使用掩码数组,2)避免使用interp1d。如果CubicSpline不够快,您可以编写自己的三次插值,并考虑到您的点是等距的。
编辑:如果您真的无法避免使用掩码数组,请注意scipy.interpolate中没有numpy.ma-aware的内容,因此您需要自己动手解决。或者,考虑进行一些数据填充以填补掩码值。

谢谢,无法避免掩码数组,这是我的数据格式。 - Amit

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