Python中隐式曲线的高阶局部插值

时间:2015-07-06 10:05:14

标签: python numpy scipy gis interpolation

给定一组描述2D平面中某些轨迹的点,我想用局部高阶插值提供该轨迹的平滑表示。

例如,假设我们在2D中定义了一个圆圈,下图中有11个点。我想在每个连续的点对之间按顺序添加点或产生平滑的轨迹。在每个段上添加点很容易,但它会产生典型的“局部线性插值”的斜率不连续性。当然,它不是经典意义上的插值,因为

  • 该函数可以为给定的y
  • 设置多个x
  • 只需在轨迹上添加更多点就可以了(不需要连续表示)。

所以我不确定这是什么词汇。

gps trajectory

生成此图的代码可以在下面找到。使用lin_refine_implicit函数执行线性插值。我正在寻找更高阶的解决方案来产生平滑的痕迹,我想知道是否有一种方法可以通过Scipy中的经典函数实现它?我尝试使用scipy.interpolate中的各种1D插值但没有取得多大成功(同样是因为给定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[:,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()

2 个答案:

答案 0 :(得分:3)

这称为参数插值。

scipy.interpolate.splprep为此类曲线提供样条近似值。这假设您知道点在曲线上的顺序

如果您不知道曲线上的哪个点出现,则问题会变得更加困难。我认为在这种情况下,这个问题被称为流形学习,而algorithms in scikit-learn中的一些可能对此有所帮助。

答案 1 :(得分:1)

我建议您尝试将笛卡尔坐标转换为极坐标,这样可以让您在没有问题的情况下使用标准scipy.interpolation,因为您不会遇到x-> y映射的模糊性了。