打印

GD32插值算法:自然样条插值 VS 抛物样条插值

[复制链接]
658|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zeshoufx|  楼主 | 2022-10-28 22:02 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zeshoufx 于 2022-10-28 22:05 编辑

插值算法运用很广,在采集数据较少的情况下,可以利用插值算法补充数据源,
常用的插值包括最邻近插值、线性插值(单线性插值和双线性插值)、样条插值;
其中样条插值包括自然样条插值、抛物样条插值;arm官方提供的样条插值就包括
这两种插值算法。
插值测试程序
#include "dsp_test.h"


static arm_spline_instance_f32  S;                                //样条插值结构体
static arm_spline_type type=ARM_SPLINE_NATURAL;        //自然样条插值
static float32_t  x[32];                                                //原始数据x
static float32_t  y[32];                                                //原始数据y
static uint32_t n=32;                                                        //原始数据个数
static float32_t  coeffs[3*(32-1)];                                //稀疏矩阵
static float32_t  tempBuffer[2*(32-1)];                        //内部计算缓冲数组
        


static float32_t  xq[128];
static float32_t  pDst[128];
static uint32_t blockSize=128;

#define num_tab 128/32

void interp_test(u8 mode)
{
        if(mode)
        {
                type=ARM_SPLINE_NATURAL;//自然样条插值
        }
        else
        {
                type=ARM_SPLINE_PARABOLIC_RUNOUT;//抛物样条插值
        }
        
        u8 i=0;
        for(i=0;i<32;i++)
        {
                x[i]=i*num_tab;
                y[i]=1.f+arm_sin_f32(100.f*PI*i/256.f+PI/3.f);
        }
        
        for(i=0;i<128;i++)
        {
                xq[i]=i;
        }
        
        arm_spline_init_f32(&S,type,x,y,n,coeffs,tempBuffer);
        arm_spline_f32(&S,xq,pDst,blockSize);
        
        printf("*****x********\r\n");
        for(i=0;i<32;i++)
        {
                printf("%f\r\n",x[i]);
        }
        printf("*****y********\r\n");
        for(i=0;i<32;i++)
        {
                printf("%f\r\n",y[i]);
        }
        
        
        printf("*****x1********\r\n");
        for(i=0;i<128;i++)
        {
                printf("%f\r\n",xq[i]);
        }
        
        printf("*****y1********\r\n");
        for(i=0;i<128;i++)
        {
                printf("%f\r\n",pDst[i]);
        }
}

测试对比一下自然样条插值和抛物样条插值两种方法
arm dsp库常量定义太多,ro-data占用空间较大
将数据拷贝到表格,导入到matlab
AB为原始数据,大小为32
C为插值后的x,大小为128
D为抛物样条插值的结果,大小为128
E为自然样条插值的结果,大小为128


主函数
/*!
    \file    main.c
    \brief   led spark with systick, USART print and key example

    \version 2014-12-26, V1.0.0, firmware for GD32F10x
    \version 2017-06-20, V2.0.0, firmware for GD32F10x
    \version 2018-07-31, V2.1.0, firmware for GD32F10x
    \version 2020-09-30, V2.2.0, firmware for GD32F10x
*/



#include "bitband.h"
#include "led.h"
#include "systick.h"
#include "print.h"
#include "dsp_test.h"

u16 mem_infor[2]={0};
u32 uid[3]={0};


int main(void)
{
    systick_set(96);
        led_init();
        
        print_config(9600);
        
        get_mem_infor(&mem_infor[0],&mem_infor[1]);
        printf("GD32F103VKT6 Flash Size=%dKB,Sram Size=%dKB...\r\n",mem_infor[1],mem_infor[0]);
        get_uid(uid);
        printf("GD32F103VKT6 UID=%d%d%d...\r\n",uid[0],uid[1],uid[2]);
        printf("\r\n抛物样条插值测试.....\r\n");
        interp_test(0);
        printf("\r\n自然样条插值测试.....\r\n");
        interp_test(1);
    while(1)
        {
                led_on();
                delay_ms(1000);
                led_off();
                delay_ms(1000);
    }
}


MATLAB程序
x=data(1:32,1);
y=data(1:32,2);
x1=data(:,3);
y1=data(:,4);
y2=data(:,5);
subplot(311)
plot(x,y),title('原始数据'),xlabel('x'),ylabel('y'),grid;
subplot(312)
plot(x1,y1),title('抛物样条插值结果'),xlabel('x'),ylabel('y'),grid;
subplot(313)
plot(x1,y2),title('自然样条插值结果'),xlabel('x'),ylabel('y'),grid;
结果

专栏细文:
程序
演示视频:
【ARM单片机插值算法,对比抛物样条插值和自然样条插值】 https://www.bilibili.com/video/BV1Sm4y1F7jc/?share_source=copy_web&vd_source=7f0cb9c0f09b768583faf157910eb515


结论:
可以看出插值后,正弦曲线变得很平滑,两者插值在细节上
无明显的区别,,只是最后几个点和趋势上抛物样条插值变缓
自然样条插值保持跟原始数据一样

inter_test.jpg (102.11 KB )

抛物样条插值VS自然样条插值

抛物样条插值VS自然样条插值

inter_test1.jpg (269.44 KB )

细节图

细节图

使用特权

评论回复
沙发
wangguanfu| | 2022-11-1 08:56 | 只看该作者
标记一下,,,

使用特权

评论回复
板凳
zeshoufx|  楼主 | 2022-11-2 21:41 | 只看该作者

也可以移植到其他板子,,

使用特权

评论回复
地板
lnhaing| | 2022-11-4 15:50 | 只看该作者
标记一下 学习下

使用特权

评论回复
5
tpgf| | 2022-11-7 15:04 | 只看该作者
三次样条插值(Cubic Spline Interpolation)简称Spline插值,是通过一系列形值点的一条光滑曲线,数学上通过求解三弯矩方程组得出曲线函数组的过程。

使用特权

评论回复
6
八层楼| | 2022-11-7 15:19 | 只看该作者
简单理解,就是每两个点之间确定一个函数,这个函数就是一个样条,函数不同,样条就不同,所以定义中说 可变样条,然后把所有样条分段结合成一个函数,就是最终的插值函数

使用特权

评论回复
7
观海| | 2022-11-7 15:29 | 只看该作者
在工程上,构造三次样条插值函数通常有两种方法:一是以给定插值结点处得二阶导数值作为未知数来求解,而工程上称二阶导数为弯矩,因此,这种方法成为三弯矩插值。二是以给定插值结点处得一阶导数作为未知数来求解,而一阶导数右称为斜率,因此,这种方法称为三斜率插值。

使用特权

评论回复
8
guanjiaer| | 2022-11-7 15:57 | 只看该作者
抛物插值(parabolic interpolation)一种插值方法.指以二次多项式为插值函数的插值方法.是九三个样点(xo , fo ) , }xl , f } ) } }xZ , fz)所做的代数拍值.

使用特权

评论回复
9
heimaojingzhang| | 2022-11-7 16:07 | 只看该作者
一元三点插值算法是一种精度更高的插值算法,使用这种方法插值出来的曲线不像线性插值算法那样在分段点的地方出现折点,显得更为平滑

使用特权

评论回复
10
keaibukelian| | 2022-11-7 16:20 | 只看该作者

如下图有A,B两点,A(x0,y0),B(x1,y1)。在A和B之间线性插入一点C,这个是一维的,只要画个图,就可以直观的看出来。这个比较简单,按照求斜率来算,可以求出。Yc=Ya+(Xc-Xa)*(Yb-Ya)/(Xb-Xa)。


使用特权

评论回复
11
zeshoufx|  楼主 | 2022-11-7 18:26 | 只看该作者
lnhaing 发表于 2022-11-4 15:50
标记一下 学习下

有开发板的话可以试一下

使用特权

评论回复
12
zeshoufx|  楼主 | 2022-11-7 18:44 | 只看该作者
tpgf 发表于 2022-11-7 15:04
三次样条插值(Cubic Spline Interpolation)简称Spline插值,是通过一系列形值点的一条光滑曲线,数学上通过 ...

遇到大佬了

使用特权

评论回复
13
zeshoufx|  楼主 | 2022-11-7 18:45 | 只看该作者
keaibukelian 发表于 2022-11-7 16:20
如下图有A,B两点,A(x0,y0),B(x1,y1)。在A和B之间线性插入一点C,这个是一维的,只要画个图,就可以直观 ...

这种线性插值在一些平滑的曲线里效果不好

使用特权

评论回复
14
zeshoufx|  楼主 | 2022-11-7 18:46 | 只看该作者
八层楼 发表于 2022-11-7 15:19
简单理解,就是每两个点之间确定一个函数,这个函数就是一个样条,函数不同,样条就不同,所以定义中说 可 ...

专业,,

使用特权

评论回复
15
zeshoufx|  楼主 | 2022-11-7 18:47 | 只看该作者
观海 发表于 2022-11-7 15:29
在工程上,构造三次样条插值函数通常有两种方法:一是以给定插值结点处得二阶导数值作为未知数来求解,而工 ...

大佬专业,,,

使用特权

评论回复
16
zeshoufx|  楼主 | 2022-11-7 18:48 | 只看该作者
guanjiaer 发表于 2022-11-7 15:57
抛物插值(parabolic interpolation)一种插值方法.指以二次多项式为插值函数的插值方法.是九三个样点(xo , f ...

又遇到专业的大佬,,向大佬学习,,

使用特权

评论回复
17
zeshoufx|  楼主 | 2022-11-7 18:48 | 只看该作者
heimaojingzhang 发表于 2022-11-7 16:07
一元三点插值算法是一种精度更高的插值算法,使用这种方法插值出来的曲线不像线性插值算法那样在分段点的地 ...

是的

使用特权

评论回复
18
weifeng90| | 2022-11-7 20:43 | 只看该作者
第一次听说这么高大上的专业词汇

使用特权

评论回复
19
zeshoufx|  楼主 | 2022-11-8 20:57 | 只看该作者
weifeng90 发表于 2022-11-7 20:43
第一次听说这么高大上的专业词汇

一些数据处理的常用方法,,

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

66

主题

1949

帖子

14

粉丝