自适应滤波C语言实现

article/2025/10/27 22:48:20

这里写目录标题

  • 原理
    • 代码
      • 结果

原理

自适应滤波是近年以来发展起来的一种最佳滤波方法。它是在维纳滤波,Kalman滤波等线性滤波基础上发展起来的一种最佳滤波方法。由于它具有更强的适应性和更优的滤波性能。从而在工程实际中,尤其在信息处理技术中得到了广泛的应用。自适应滤波存在于信号处理、控制、图像处理等许多不同领域,它是一种智能更有针对性的滤波方法,通常用于去噪。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210311120044984.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQyMjA5OTc3,size_16,color_FFFFFF,t_70在这里插入图片描述
在这里插入图片描述
本人理解的自适应滤波是输入X(N)变量值和自适应滤波滤波器系数W(n)进行矩阵相乘得到系统输出的Y(j),Y(j)和期望信号D(n)相减得到差值E(n).通过不断的迭代得到合适的滤波器系数W(N+1)。

代码

参考:https://blog.csdn.net/xdzhujy/article/details/105638797?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161543561316780255269410%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161543561316780255269410&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-6-105638797.pc_search_result_cache&utm_term=%E8%87%AA%E9%80%82%E5%BA%94%E7%AE%97%E6%B3%95

上诉博主理论和MATLAB代码说得很详细,在他MATLAB代码的基础,理解了一下,写出C语言代码,运行环境Microsft Visual Studio.
下面展示一些 内联代码片

#include<stdio.h>
#define F_COUNT 1024
#define M 15
/* xn--------输入的信号序列(列向量)* itr-------迭代次数,标量,默认为xn的长度,M<itr<sizeof(xn)* en--------误差序列(itr*1)列向量* dn--------所期望的响应序列(列向量)* M---------滤波器的阶数(标量)* mu--------收敛因子(步长)标量* W---------滤波器权值矩阵,大小为M*itr* yn--------实际输出序列(列向量)*/float xn[250] = { 10,10.2,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,10.1,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,10.2,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,10,9.8,10,10.1,9.9,10.10,10.2,9.78,9.9,10, 10,9,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10,10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10, 10,9.8,9.8,10,10.1,9.9,10.1,10.2,9.78,9.9,10,20.0,20.1,20.2,20.3,20.4,20.5,20.6,20.7,20.8,20.9,21,21.1,21.2,21.3,21.4,21.5,21.6,21.7,21.8,21.9,22,22.1,22.2,22.3,22.4,22.51,22.62,22.72,22.78,22.89,23.02,23.12,23.18,23.31,23.42,23.53,23.62,23.67,23.78,23.89,24.02,24.08,24.18,24.32,24.38,24.52,24.61,24.74,24.81,24.92,25,25.1 };
float dn[251] = {10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10 ,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,20.0,20.1,20.2,20.3,20.4,20.5,20.6,20.7,20.8,20.9,21,21.1,21.2,21.3,21.4,21.5,21.6,21.7,21.8,21.9,22,22.1,22.2,22.3,22.4,22.5,22.6,22.7,22.8,22.9,23.0,23.1,23.2,23.3,23.4,23.5,23.6,23.7,23.8,23.9,24.0,24.1,24.2,24.3,24.4,24.5,24.6,24.7,24.8,24.9,25 };float* LMS_Filter(int itr, const float* xn, const float* dn, double mu, int length)
{static int i = 0;static int k = 0;static float y = 0.0;static float en[F_COUNT];static float W[M];//static float W[M][F_COUNT];static float x[M];static float yn[F_COUNT];//下面两行代码打印出xn原始数据,需要可以取消注释//for (i = 0; i < 250; i++)//	printf("y=%f   k=%d\n", xn[i], i);for(i=0;i<M;i++)printf("y=%f   k=%d\n", xn[i], i);/*创建一个en全零矩阵,en(k)表示第k次迭代时预期输出与实际输入的误差*/for (i = 0; i < itr; i++){en[i] = 0;}/*创建一个W全零矩阵,每一行代表一个加权参量,每一列代表一次迭代*/for (i = 0; i < M; i++)W[i] = 0;/*创建一个x全零矩阵*/for (i = 0; i < M; i++)x[i] = 0;/*迭代计算*/for (k = M; k <= itr; k++){/* 滤波器M个抽头的输入:从xn第k-1个值倒序取出M个样点的值放入x* y为滤波器输出:W的第K-2列与x的积的和*/for (i = 0; i < M; i++){x[i] = xn[k-i-1];}for (i = 0; i < M; i++)y += W[i] * x[i];   //卷积乘法en[k] = dn[k] - y;  //第k次迭代的误差/*滤波器权值计算的迭代式*/for (i = 0; i < M; i++){W[i] = W[i]+  mu * en[k] * x[i];}printf("y=%f   k=%d\n", y,k);y = 0.0;}return yn;
}
int main()
{LMS_Filter(250, xn, dn, 0.0008, 250);printf("hellow");
}

结果

在这里插入图片描述


在这里插入图片描述
经过自适应滤波后,确实起到滤波效果,而且在前后段数据波动较大时,系统也可以很快的拟合数据。效果比固定拟合系数的卡尔曼滤波好。代码中xn是原始数据,DN是期望数据,代码中可以更改步长,和滤波器阶数。有啥问题评论区留言,一起探讨,博主也是半懂不懂。


http://chatgpt.dhexx.cn/article/h9vS0XSa.shtml

相关文章

c语言实现图像滤波处理

#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include <math.h> /* 位图头结构 */ #pragma pack(1) typedef struct tagBITMAPFILEHEADER {unsigned char bfType[2];//文件格式unsigned long bfSize;//文件大小unsigned short bfReserve…

卡尔曼滤波一阶矩阵C语言实现

①估计时刻k的状态&#xff1a; ②误差相关矩阵P&#xff0c;度量估计值的精确程度 ③卡尔曼增益 ④更新误差相关矩阵 ⑤更新状态变量 ⑥最后输出 C语言代码&#xff1a; float X_pre,P_pre,X_kalman_last,P_kalman_last,X_kalman2500,P_kalman2; //赋初值 float H,Q…

卡尔曼滤波C语言实现

卡尔曼5条基本公式&#xff0c;参考https://wenku.baidu.com/view/8523cb6eaf1ffc4ffe47ac24.html #include "stdio.h" #include "stdlib.h" #include "math.h"#define kal_Q 0.001 /*过程噪声协方差,Q增大&#xff0c;动态响应变快&#xff0…

C语言实现简单卡尔曼滤波

https://www.bilibili.com/video/BV1ez4y1X7eR DR.CAN讲的真的很好 卡尔曼滤波的步骤 步骤说明Step 1计算卡尔曼增益Step 2更新本次迭代的估计值Step 3更新本次迭代的估计误差 具体请看上面DR.CAN的视频 代码 参数说明x_mea测量值x_est估计值e_mea固有的测量误差&#xf…

C语言实现双边滤波

参考博文 看不懂公式的先去看参考博文 一个3*3窗口的代码 /**双边法滤波 3*3窗口 *参数 data[][COL] 图像数据 *参数 row 图像数据行数 *参数 varD 空域核d的标准差 *参数 varR 值域核r的标准差 *需要引用头文件math.h *typedef unsi…

数字图像处理,读懂频域处理的“傅里叶变换”

转载自&#xff1a;https://blog.csdn.net/ebowtang/article/details/39004979 以下部分文字资料整合于网络&#xff0c;本文仅供自己学习用&#xff01; 这是一幅很绝的一维傅里叶变换动态图 一&#xff0c;读懂傅里叶变换 一个信号能表示成傅里叶级数的形式是有条件的&…

傅立叶变换和拉普拉斯变换

欧拉公式 证明过程如下 首先是泰勒展开 参考cosX和sinX的泰勒展开可以证明这个问题。 还有下面这个号称宇宙最美公式 “自然底数e&#xff0c;自然数1和0&#xff0c;虚数i还有圆周率pi&#xff0c;它是这么简洁&#xff0c;这么美丽啊&#xff01;” 傅立叶级数 傅立叶在…

Little’s Law 利特尔法则

1 A simple definition: Little’s Law states that the long-term average number of customers in a stable system L L L is equal to the long-term average effective arrival rate, λ \lambda λ, multiplied by the average time a customer spends in the system, …

勒让德符号的说明及作用

Legendre符号的用途 一、 二次剩余 勒让德符号的提出的意义是判断一个数是否是模n的二次剩余&#xff0c;所以研究勒让德符号之前应该了解一下二次剩余。 存在x使x的平方与a MOD (p)就称a为模p的二次剩余&#xff0c;其中p为素数&#xff0c;a>0且a<p。 通过勒让…

奈奎斯特准则的简洁证明

一般而言&#xff0c;发送滤波器和接收滤波器的冲激响应相同且关于原点对称&#xff0c;有用信号事实上经过了这两个滤波器&#xff0c;所以等效滤波器为&#xff1a; 为使无符号间干扰&#xff0c; 应满足&#xff1a; 奈奎斯特准则指出上式等价于&#xff1a; 其中 表示的傅里…

蒙蒂霍尔悖论

贝叶斯与频率主义对蒙蒂霍尔问题的解 在定义概率时&#xff0c;通常有两种思想流派&#xff1a;贝叶斯主义和频率主义。前者将概率视为我们对事件发生的信念程度&#xff0c;而后者则将其视为事件发生的相对频率。这篇文章介绍了使用贝叶斯和频率主义方法来解决著名的蒙蒂霍尔问…

信号 信号的线性放大

信号 1.信号 信号是信息的载体或表达形式 2. 信号的频谱 正弦信号 方波信号 满足狄里赫利条件&#xff0c;展开成傅里叶级数 附 狄里赫利条件: 1) 函数在任意有限区间内连续&#xff0c;或只有有限个第一类间断点&#xff08;当t从左或右趋于这个间断点时&#xff0c;函数有有限…

信号的频域描述

一、周期信号的频域描述 1. 狄里赫利条件 &#xff08;1&#xff09;函数在任意有限区间内连续&#xff0c;或只有有限个第一类间断点 &#xff08;2&#xff09;在一个周期内&#xff0c;函数有有限个 极大值或极小值 2. 傅里叶级数 &#xff08;1&#xff09;傅里叶级数…

【信号与系统】(十三)傅里叶变换与频域分析——周期信号的傅里叶级数

文章目录 周期信号的傅里叶级数1 周期信号三角形式的傅里叶级数1.1 三角形式的傅里叶级数1.2 狄里赫利(Dirichlet)条件1.3 .余弦形式的傅里叶级数1.4 吉布斯现象 2 周期信号波形对称性和谐波特性2.1 f ( t ) f(t) f(t)为偶函数2.2 f ( t ) f(t) f(t)为奇函数2.3 f ( t ) f(t…

连续时间傅立叶变换和拉普拉斯变换

连续时间傅里叶变换简称&#xff1a;CTFT 连续时间周期信号x(t)如果满足狄里赫利条件&#xff0c;则其存在傅立叶级数对&#xff1a; x(t)在任何有限区间内&#xff0c;有有限个不连续点&#xff0c;并且在每个不连续点都必须是有限值。 注意&#xff1a;狄里赫利条件是充分条…

狄利克雷条件

属于 傅里叶级数分析使用的条件&#xff1a; 傅里叶在提出 傅里叶级数时坚持认为&#xff0c;任何一个周期信号都可以展开成傅里叶级数&#xff0c;虽然这个结论在当时引起许多争议&#xff0c;但持异议者却不能给出有力的不同论据。直到20年后(1829年)狄里赫利才对这个问题作出…

从傅里叶变换到拉普拉斯变换

理解拉普拉斯变换&#xff0c;可以先从傅里叶变换开始。 傅里叶定律&#xff1a;只要一个函数满足如狄利赫里条件&#xff0c;都能分解为复指数函数之和。 狄利赫里条件&#xff1a; (1) 函数在任意有限区间内连续&#xff0c;或只有有限个第一类间断点&#xff1b; (2)在一…

周期信号的傅里叶级数

周期信号的傅里叶级数 周期信号三角形式的傅里叶级数 1.三角形式的傅里叶级数 系数an, bn称为傅里叶系数 2.狄里赫利(Dirichlet)条件&#xff1a; 条件1&#xff1a;在一个周期内&#xff0c;函数连续或只有有限个第一类间断点&#xff1b; 条件2&#xff1a;在一个周期内&…

【Spring Boot】请求参数传json对象,后端采用(pojo)CRUD案例(102)

请求参数传json对象&#xff0c;后端采用&#xff08;pojo&#xff09;接收的前提条件&#xff1a; 1.pom.xml文件加入坐标依赖&#xff1a;jackson-databind 2.Spring Boot 的启动类加注解&#xff1a;EnableWebMvc 3.Spring Boot 的Controller接受参数采用&#xff1a;Reque…

8.返回JSON数据(Jackson):【@Controller + @ResponseBody 等价于【@RestController】的使用方法 jackson乱码的xml配置

文章目录 Controller类&#xff0c;返回JSON数据(Jackson)【一个不乱码的对象】1. 使用Jackson&#xff0c;需要额外导入pom依赖&#xff1a;jackson-databind2. 配置web.xml&#xff1a;注册DispatcherServlet、自带的过滤器3. 配置springmvc-servlet.xml 【含jackson乱码的解…