Python 中隐式曲线的高阶局部插值
Higher order local interpolation of implicit curves in Python
给定一组描述 2D 平面中某些轨迹的点,我想通过局部高阶插值提供该轨迹的平滑表示。
例如,假设我们在下图中用11个点定义一个二维圆。我想按顺序在每对连续的点之间添加点或产生平滑的轨迹。在每个段上添加点很容易,但它会产生 "local linear interpolation" 的典型坡度不连续性。当然不是经典意义上的插值,因为
- 对于给定的
x
,函数可以有多个 y
值
- 简单地在轨迹上添加更多点就可以了(不需要连续表示)。
所以我不确定什么是合适的词汇。
可以在下面找到生成此图的代码。使用 lin_refine_implicit
函数执行线性插值。我正在寻找一个更高阶的解决方案来产生平滑的轨迹,我想知道是否有一种方法可以用 Scipy 中的经典函数来实现它?我尝试使用 scipy.interpolate
中的各种 1D 插值但没有取得太大成功(同样是因为给定 x
有多个 y
值)。
最终目标是使用这种方法从离散测量中提供平滑的 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[:,0], xy_highres_lin[:,1], '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()
我建议您尝试将笛卡尔坐标转换为极坐标,这样您就可以毫无问题地使用标准 scipy.interpolation
,因为您不会再有 x->y 映射的模糊性.
这称为参数插值。
scipy.interpolate.splprep 为此类曲线提供样条近似值。这假设您知道点在曲线上的 [=18=] 顺序 。
如果你不知道曲线上的哪个点在哪个点之后,问题就变得更难了。我认为在这种情况下,这个问题称为流形学习,algorithms in scikit-learn 中的一些内容可能对此有所帮助。
给定一组描述 2D 平面中某些轨迹的点,我想通过局部高阶插值提供该轨迹的平滑表示。
例如,假设我们在下图中用11个点定义一个二维圆。我想按顺序在每对连续的点之间添加点或产生平滑的轨迹。在每个段上添加点很容易,但它会产生 "local linear interpolation" 的典型坡度不连续性。当然不是经典意义上的插值,因为
- 对于给定的
x
,函数可以有多个 - 简单地在轨迹上添加更多点就可以了(不需要连续表示)。
y
值
所以我不确定什么是合适的词汇。
可以在下面找到生成此图的代码。使用 lin_refine_implicit
函数执行线性插值。我正在寻找一个更高阶的解决方案来产生平滑的轨迹,我想知道是否有一种方法可以用 Scipy 中的经典函数来实现它?我尝试使用 scipy.interpolate
中的各种 1D 插值但没有取得太大成功(同样是因为给定 x
有多个 y
值)。
最终目标是使用这种方法从离散测量中提供平滑的 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[:,0], xy_highres_lin[:,1], '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()
我建议您尝试将笛卡尔坐标转换为极坐标,这样您就可以毫无问题地使用标准 scipy.interpolation
,因为您不会再有 x->y 映射的模糊性.
这称为参数插值。
scipy.interpolate.splprep 为此类曲线提供样条近似值。这假设您知道点在曲线上的 [=18=] 顺序 。
如果你不知道曲线上的哪个点在哪个点之后,问题就变得更难了。我认为在这种情况下,这个问题称为流形学习,algorithms in scikit-learn 中的一些内容可能对此有所帮助。