给定一个屏蔽的 NumPy 维数数组 (frames, points, 2)
代表frames
的视频帧,其中每一帧points
(x, y)
点正在被跟踪。
我想从 frames
插入此视频帧到任意数量的帧,非常快,希望使用三次样条,但任何其他连续插值也可以正常工作。
我实现的天真解决方案将数组拆分为 2 个维度数组 (frames, points)
为 X
数组和 Y
大批。
然后,我将数组转置为 (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 frames, 140 points, 2)
至 (24 frames, 140 points, 2)
笔记!
这是一个掩码数组,如
[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]
最佳答案
我不确定您是否在使用 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)
关于python - 使用 NumPy 进行快速插值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60758017/