前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python中的曲线插值算法

Python中的曲线插值算法

作者头像
YoungTimes
发布2022-04-28 19:31:19
2K0
发布2022-04-28 19:31:19
举报

在实际应用中需要对路径或者曲线进行重采样,重采样的过程就是"曲线拟合->重采样曲线点"的过程。

1.待解决问题

如下一系列点组成的曲线,我们需要对曲线进行拟合重采样。

代码语言:javascript
复制
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

from scipy.interpolate import UnivariateSpline

from scipy.interpolate import interp1d

# Define some points:
theta = np.linspace(-3, 2, 40)
points = np.vstack( (np.cos(theta), np.sin(theta)) ).T

# add some noise:
points = points + 0.05 * np.random.randn(*points.shape)

plt.plot(*points.T, 'ok')
plt.plot(*points.T, '-r')

plt.show()

2. 拟合重采样过程遇到的问题

下面的方法都不Work!!

2.1 Cubic Interpolation

代码语言:javascript
复制
def cubic_interpolation(fig, axs):
    xnew = np.linspace(x_arr.min(), x_arr.max(), len(x_arr))
    f = interpolate.interp1d(xnew , y_arr, kind='cubic')

    axs.plot(xnew, f(xnew))
    axs.set_title('cubic')

2.2 Cubic Spline Interpolation

代码语言:javascript
复制
def cubic_spline_interpolation(fig, axs):
    xnew = np.linspace(x_arr.min(), x_arr.max(), len(x_arr))
    tck = interpolate.splrep(x_arr, y_arr, s=0)
    ynew = interpolate.splev(xnew, tck, der=0)

    axs.plot(xnew, ynew)
    axs.set_title('cubic spline')

Always Fail (ValueError: Error on input data)

原因: 函数要求x严格从小到大有序。

2.3 Parametric Spline Interpolation

代码语言:javascript
复制
def parametric_spline_interpolation(fig, axs):
    xnew = np.linspace(x_arr.min(), x_arr.max(), len(x_arr))
    tck, u = interpolate.splprep([x_arr, y_arr], s=0)
    out = interpolate.splev(xnew, tck)

    axs.plot(out[0], out[1])
    axs.set_title('parametric spline')

2.4 Univariate Spline Interpolation

代码语言:javascript
复制
def univariate_spline_interpolated(fig, axs):   
    s = interpolate.InterpolatedUnivariateSpline(x_arr, y_arr)# ValueError: x must be strictly increasing
    xnew = np.linspace(x_arr.min(), x_arr.max(), len(x_arr))
    ynew = s(xnew)

    axs.plot(xnew, ynew)
    axs.set_title('univariate spline')

错误:ValueError: x must be strictly increasing

2.5 Rbf Interpolation

代码语言:javascript
复制
def rbf(fig, axs):
    xnew = np.linspace(x_arr.min(), x_arr.max(), len(x_arr))
    rbf = interpolate.Rbf(x_arr, y_arr) # numpy.linalg.linalg.LinAlgError: Matrix is singular.
    fi = rbf(xnew)

    axs.plot(xnew, fi)
    axs.set_title('rbf')

2.6 Linear Interpolation

代码语言:javascript
复制
def linear_interpolation(fig, axs):
    xnew = np.linspace(x_arr.min(), x_arr.max(), len(x_arr))
    f = interpolate.interp1d(xnew , y_arr)

    axs.plot(xnew, f(xnew))
    axs.set_title('linear')

3.UnivariateSpline曲线拟合采样

将x和y作为曲线offset的函数分别拟合,解决了拟合函数对自变量必须严格从小到大有序的要求。

代码语言:javascript
复制
# Linear length along the line:
distance = np.cumsum(np.sqrt(np.sum(np.diff(points, axis = 0)**2, axis = 1 )) )

distance = np.insert(distance, 0, 0)/distance[-1]

# Build a list of the spline function, one for each dimension:
splines = [UnivariateSpline(distance, coords, k=3, s=0) for coords in points.T]

# Computed the spline for the asked distances:
alpha = np.linspace(np.min(distance), np.max(distance), 75)
points_fitted = np.vstack(spl(alpha) for spl in splines).T

# Graph:
plt.plot(*points_fitted.T, 'ok', label='original points')
plt.plot(*points_fitted.T, '-r', label='fitted spline k=3, s=0')
plt.axis('equal')
plt.legend();
plt.xlabel('x')
plt.ylabel('y')

plt.show()

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 半杯茶的小酒杯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.待解决问题
  • 2. 拟合重采样过程遇到的问题
    • 2.1 Cubic Interpolation
      • 2.2 Cubic Spline Interpolation
        • 2.3 Parametric Spline Interpolation
          • 2.4 Univariate Spline Interpolation
            • 2.5 Rbf Interpolation
              • 2.6 Linear Interpolation
              • 3.UnivariateSpline曲线拟合采样
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档