分段插值方法和code,cubic spline, cubic hermite spline

15 篇文章 0 订阅
8 篇文章 0 订阅

0. 引入

在 Non-Rigid Dense Correspondence with Applications for Image Enhancement 和 Exposure Stacks of Live Scenes with Hand-Held Cameras中 使用了分段函数拟合的方法: cubic spline 和 cubic hermite spline。
cubic是三次插值函数,每一段都是cubic函数,连接在一起构成spline.

1.Cubic Spline Interpolation

Cubic Spline Interpolation清晰的讲解和python示例

from scipy.interpolate import CubicSpline
import numpy as np
import matplotlib.pyplot as plt

plt.style.use('seaborn-poster')
x = [0, 1, 2]
y = [1, 3, 2]

# use bc_type = 'natural' adds the constraints as we described above
f = CubicSpline(x, y, bc_type='natural')
x_new = np.linspace(0, 2, 100)
y_new = f(x_new)
plt.figure(figsize = (10,8))
plt.plot(x_new, y_new, 'b')
plt.plot(x, y, 'ro')
plt.title('Cubic Spline Interpolation')
plt.xlabel('x')
plt.ylabel('y')
plt.show()

在这里插入图片描述

2. 多项式插值

多项式插值,顾名思义,即以一个多项式的形式来刻画经过一系列点的曲线。
比如拉格朗日插值 和牛顿插值,无论是Lagrange插值还是Newton插值,本质都是用一个多项式来进可能精确地描绘过节点的原始函数。但多项式插值的矛盾之处在于,若节点太少,则插值出来的函数与原始函数可能偏离较大,返回的插值结果对于实际的指导用处不大;但若节点太多,则多项式的阶数也会需要相应增加,但太高的阶数容易又会导致绘制出的插值曲线在边缘处不稳定,这便是龙格现象

在这里插入图片描述

不同插值方法的比较及Python实现

3. 分段插值

多项式插值容易产生龙格现象,这时候可以使用分段插值。

常见的分段插值主要有分段线性插值,分段三次Hermite插值以及分段三次样条插值。
下面的博客介绍的很清楚:
参考
1.不同插值方法的比较及Python实现
2. Cubic Hermite Spline之二
3. 可以指定函数值和斜率的cubic hermite spline python lib

from chspy import CubicHermiteSpline
from matplotlib.pyplot import subplots

spline = CubicHermiteSpline(n=3)

#            time   state    slope
spline.add((   0 , [1,3,0], [0,1,0] ))
spline.add((   1 , [3,2,0], [0,4,0] ))
spline.add((   4 , [0,1,3], [0,4,0] ))

fig,axes = subplots(figsize=(7,2))
spline.plot(axes)
axes.set_xlabel("time")
axes.set_ylabel("state")
fig.legend(loc="right",labelspacing=1)
fig.subplots_adjust(right=0.7)

得到:
在这里插入图片描述

4. Monotone Cubic Interpolation单调的分段插值code

4. scipy.interpolate中的插值方法

4.1 cubic hermite spline插值类

class scipy.interpolate.CubicHermiteSpline
class scipy.interpolate.PchipInterpolator 单调

4.2 cubic spline插值类

class scipy.interpolate.CubicSpline
class scipy.interpolate.Akima1DInterpolator 完全通过给的点

Akima1DInterpolator拟合分段三次多项式,给定向量x和y。生成的曲线通过给定的数据点,看起来平滑自然。
仅用于精确的数据,因为拟合曲线精确地通过给定的点。

'''
cubic hermite :节点处一阶导数相等
cubic :节点处二阶导数相等,因此更加平滑,更加扭曲
Akima1DInterpolator : cubic 分段插值,但是拟合的曲线会通过给定点
PchipInterpolator :monotonic cubic hermite ,在分段区间内都是单调的。
'''

4.3 示例和代码:

gt是groundtruth 曲线
node是生成的带噪声的点

其他是使用上面4个函数拟合得到曲线。

在这里插入图片描述
完整code 如下:

"""
分段函数拟合
"""
import numpy as np
import scipy
from matplotlib import pyplot as plt

def fun(xx, fig=0):
    # xx = np.linspace(0, 1, 100)
    yy1 = np.sin(xx * 10)
    yy2 = (xx - 2) ** 2 * np.sqrt(xx ** 4 + 1)
    yy3 = xx / 10.4 * np.log(20 * xx ** 2 + 1)

    yy = yy1 + yy2 + yy3
    if fig:
        plt.figure()
        plt.plot(xx, yy1, 'r-', xx, yy2, 'g-', xx, yy3, 'b-', xx, yy, 'k-')
        plt.show()
    return yy
if __name__ == "__main__":
    xx = np.linspace(0, 1, 100)
    yy = fun(xx, 1)

    np.random.seed(2)
    xx1 = np.linspace(0, 1, 6)
    yy1 = fun(xx1) + np.random.randn(len(xx1)) * 0.2
    plt.figure()
    plt.plot(xx1, yy1, 'r+', xx, yy, 'k-')
    plt.show()

    dy = np.zeros_like(yy1)
    dy[:-1] = yy1[1:] - yy1[:-1]
    interp_1 = scipy.interpolate.CubicHermiteSpline(xx1, yy1, dy )
    yy_pred_1 = interp_1(xx)

    interp_1 = scipy.interpolate.PchipInterpolator(xx1, yy1)
    yy_pred_2 = interp_1(xx)

    interp_1 = scipy.interpolate.CubicSpline(xx1, yy1)
    yy_pred_3 = interp_1(xx, 0)

    interp_1 = scipy.interpolate.Akima1DInterpolator(xx1, yy1)
    yy_pred_4 = interp_1(xx)

    plt.figure()
    plt.plot(xx1, yy1, 'kx', label='node')
    plt.plot( xx, yy_pred_1, 'r-', label='cubic hermite')
    plt.plot( xx, yy_pred_2, 'g-', label='monotonic cubic hermite')
    plt.plot( xx, yy_pred_3, 'b-', label=' cubic ')
    plt.plot(xx, yy_pred_4, 'y-', label=' cubic through p')
    plt.plot(xx, yy, 'k-', label=' gt')
    plt.legend()
    plt.show()
    '''
    cubic hermite :节点处一阶导数相等
    cubic :节点处二阶导数相等,因此更加平滑,更加扭曲
    Akima1DInterpolator : cubic 分段插值,但是拟合的曲线会通过给定点
    PchipInterpolator :monotonic cubic hermite ,在分段区间内都是单调的。
    '''
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB提供了多种插值方法,具体取决于用户的需求和数据的特点。以下是几种常用的MATLAB插值方法: 1. 最近邻点插值(nearest): 这种方法会直接使用最接近插值点的已知数据点的函数值来进行插值插值结果可能会有突变的情况。 2. 线性插值(linear): 这种方法会通过已知数据点之间的直线来进行插值插值结果会保持函数值之间的线性关系,并且相对平滑。 3. 三次样条函数插值spline): 这种方法会根据已知数据点之间的三次多项式曲线来进行插值插值结果会保持函数值的连续性,并且相对平滑。 4. 分段三次Hermite插值cubic): 这种方法会根据已知数据点的一阶导数信息来进行插值插值结果除了保持连续性和平滑性外,还会尽量保持原函数的曲率特性。 5. 三次多项式插值(v5cubic): 这种方法是一种更高阶的插值方法,会根据已知数据点之间的三次多项式来进行插值。它可以在计算复杂度与插值质量之间取得平衡。 用户可以根据自己的需求和数据的特点选择适合的插值方法。需要注意的是,对于超出已知数据的插值点,使用某些方法可能会返回NaN(不是一个数)作为插值结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [matlab的插值方法](https://blog.csdn.net/gy99csdn/article/details/82025469)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值