问题描述
这称为参数插值。
scipy.interpolate.splprep提供此类曲线的样条曲线近似值。假设您知道点在曲线上的顺序 。
如果您不知道曲线上哪个点之后,该问题将变得更加困难。我认为在这种情况下,这个问题称为流形学习,而scikit- learn中的某些算法可能对此有所帮助。
解决方法
给定一组描述2D平面中某些轨迹的点,我想使用局部高阶插值提供该轨迹的平滑表示。
例如,假设我们在下图中定义了一个11点的2D圆。我想按顺序在每对连续的点之间添加点,或产生平滑的轨迹。在每个线段上添加点很容易,但是会产生“局部线性插值”中典型的斜率不连续性。当然,这不是经典意义上的插值,因为
- 该函数可以
y
给定多个值x
- 只需在轨迹上添加更多点就可以了(不需要连续表示)。
所以我不确定什么是合适的词汇
可以在下面找到产生该图形的代码。线性插补通过lin_refine_implicit
功能执行。我正在寻找一种更高阶的解决方案来产生平滑的轨迹,并且我想知道Scipy中是否可以使用经典功能来实现它?我尝试过使用各种1D插值,scipy.interpolate
但均未获得很大的成功(同样由于y
给定的多个值x
)。
最终目标是使用此方法通过离散测量提供平滑的GPS轨迹,因此我认为这应该在某个地方有经典的解决方案。
import numpy as np
import matplotlib.pyplot as plt
def lin_refine_implicit(x,n):
"""
Given a 2D ndarray (npt,m) of npt coordinates in m dimension,insert 2**(n-1) additional points on each trajectory segment
Returns an (npt*2**(n-1),m) ndarray
"""
if n > 1:
m = 0.5*(x[:-1] + x[1:])
if x.ndim == 2:
msize = (x.shape[0] + m.shape[0],x.shape[1])
else:
raise NotImplementedError
x_new = np.empty(msize,dtype=x.dtype)
x_new[0::2] = x
x_new[1::2] = m
return lin_refine_implicit(x_new,n-1)
elif n == 1:
return x
else:
raise ValueError
n = 11
r = np.arange(0,2*np.pi,2*np.pi/n)
x = 0.9*np.cos(r)
y = 0.9*np.sin(r)
xy = np.vstack((x,y)).T
xy_highres_lin = lin_refine_implicit(xy,n=3)
plt.plot(xy[:,0],xy[:,1],'ob',ms=15.0,label='original data')
plt.plot(xy_highres_lin[:,xy_highres_lin[:,'dr',ms=10.0,label='linear local interpolation')
plt.legend(loc='best')
plt.plot(x,y,'--k')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('GPS trajectory')
plt.show()