给定一个蒙面NumPy数组的维数,(frames, points, 2)
表示frames
帧的视频,在每个帧中,points
(x, y)
点被跟踪。
我想插值这个视频从frames
帧到任何数目的帧,非常快,希望使用三次样条,但任何其他连续插值也会工作得很好。
我所实现的天真解决方案将数组拆分为两个维度数组,即(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)
的小数组
seconds
注意!
这是一个蒙面数组,类似于[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]
发布于 2020-03-19 15:37:55
我不确定你是否像我一样使用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)
发布于 2020-03-20 05:23:10
如果您需要它的快速,1)避免蒙面数组,2)避免interp1d。如果CubicSpline不够快,你可以在考虑到你的点是等距的情况下对你自己的三次插值进行编码。
编辑:如果您真的无法避免蒙面数组,请注意scipy.interpolate中没有任何东西是numpy.ma感知的,所以您需要进行DIY。或者,考虑做一些数据计算来填充蒙面值。
https://stackoverflow.com/questions/60758017
复制相似问题