浅谈自适应滤波器---(自适应陷波器)

article/2025/10/9 22:04:52

          陷波器顾名思义就是对特定频率的信号有着很强的衰减的滤波器,也即阻带带宽极窄的带阻滤波器。在传统的数字陷波器设计中,为了能使某一频率信号得到足够大的衰减,通常的做法就是把阶数选的足够高来达到很大的衰减;但同时计算量也变得更大了。而且设计的过程复杂,不利于动态的调整。为了解决上述存在的问题自适应陷波器孕育而生。博主在一次心电信号(ECG)工频干扰滤除的项目中就使用了自适应陷波器,其效果要远远好于传统的陷波器,它能在信干比-100dB的时候依然能够很好的将有用的信号提取出来。

       当我们知道原始信号里的干扰信号频率是多少时(例如最常见的50Hz工频干扰),这时我们只需要知道这个干扰信号的相位和幅度,然后就可以完全的“再现”这个干扰信号,然后我们就可以直接的从原始信号中将其减去,从而就得到了我们想要的信号成分。这一过程实际上就是自适应陷波器的基本工作原理。关于自适应实现算法的具体原理可以参考博主之前写过的博客文章《浅谈自适应滤波器》,下面给出的是今天要介绍的自适应陷波器的结构图:


       其中x(k)是带有特定频率干扰的信号,也即输入的原始信号,可见它是从自适应滤波器的期望信号端输入的;而sin(2π f0/fs k)和cos(2π f0/fs k),是我们已知的频率为f0的干扰信号(其中fs是采样率),将它们分别乘以W1和W2进行适当的线性组合,就可以使其输出y(k)接近实际的干扰,最后输出的误差e(k)就是我们感兴趣的信号。如何进行W1和W2的选择这其实是自适应算法需要完成的工作,具体来说就是采用某种准则来构建一个关于误差e(k)的函数,通过是误差e(k)最小化来求得W1和W2,最常用的准则就是使误差的均方和最小。这也是本次博主要和大家分享的具体的自适应陷波器。

Matlab仿真

首先给出的是基于LMS的瞬时梯度估计算法的仿真代码:

clc;
clear all;
close all;
%%
%************************生成仿真信号**************************************
Fs = 500;                                                     %设置采样频率
t = 0:1/Fs:3;  
t = t';
Size_t = size(t,1);
F1 = 7;
F2 = 13;
F3 = 23;
F4 = 50;
SNR = -100;            %信干比 Unit:dBSignal = 10^(SNR/20)*(sin(2*pi*F1*t) + 0.5*sin(2*pi*F2*t) + 0.25*sin(2*pi*F3*t)); %生成信号
noise = 0.95*sin(2*pi*F4*t+pi/2);
Signal_noise = Signal + noise;                               %加入50Hz工频干扰%%
%*************************************************************************
M = 2;                                    %定义FIR滤波器阶数
Signal_Len = Size_t;                      %定义信号数据的个数
niu = 1;                                  %算法调节步长控制因子
y_out = zeros(Signal_Len,1);              %滤波器输出
error_out = zeros(Signal_Len,1);          %误差输出            
w_out = zeros(Signal_Len,M);              %系数输出
for i=1:Signal_Len%数据输入if i == 1           %如果是第一次进入w = zeros(M,1); %初始化滤波器抽头系数x = zeros(M,1); %初始化信号向量endd = Signal_noise(i);                     %输入新的期望信号x = [sin(2*pi*F4*(i-1)/Fs)cos(2*pi*F4*(i-1)/Fs)];                 %输入新的信号矢量%算法正体y = x' * w;                              %计算滤波器输出error = d - y;                           %计算误差w_forward = w + niu * error * x;         %计算滤波器系数向量%变量更替w = w_forward;%滤波结果存储y_out(i) = y;error_out(i) = error;w_out(i,:) = w';
end
%%
subplot(2,1,1);
plot(t,Signal);
title('原始信号');
xlabel('时间t/s');
subplot(2,1,2);
plot(t,Signal_noise);
title('加入干扰噪声的信号');
xlabel('时间t/s');figure;
subplot(2,1,1);
plot(t,y_out);
title('滤波器输出');
xlabel('时间t/s');
subplot(2,1,2);
plot(t,error_out,'b');
title('输出误差');
xlabel('时间t/s');
axis([0,3,-3*10^-5,3*10^-5]);figure;
plot(t(1:Signal_Len),w_out(1),'r',t(1:Signal_Len),w_out(2),'b');
title('自适应滤波器系数');
xlabel('时间t/s');
运行一下得到如下的结果:



可以看到在信干比-100dB的情况下,有用的信号得到了不错的恢复。

接下来给出的是基于RLS的仿真代码:

clc;
clear all;
close all;
%%
%************************生成仿真信号**************************************
Fs = 500;                                                     %设置采样频率
t = 0:1/Fs:3;  
t = t';
Size_t = size(t,1);
F1 = 7;
F2 = 13;
F3 = 23;
F4 = 50;
SIR = -100;            %信干比 Unit:dBSignal = 10^(SIR/20)*(sin(2*pi*F1*t) + 0.5*sin(2*pi*F2*t) + 0.25*sin(2*pi*F3*t)); %生成信号
noise = 0.95*sin(2*pi*F4*t + pi/4);
Signal_noise = Signal + noise;                               %加入50Hz工频干扰%%
%*************************************************************************
M = 2;                         %定义FIR滤波器阶数
lamda = 0.90;                  %定义遗忘因子     
Signal_Len = Size_t;           %定义信号数据的个数
I = eye(M);                    %生成对应的单位矩阵
c = 0.01;                      %小正数 保证矩阵P非奇异
y_out = zeros(Signal_Len,1);
Eta_out = zeros(Signal_Len,1);
w_out = zeros(Signal_Len,M);
for i=1:Signal_Len%输入数据if i == 1                 %如果是第一次进入P_last = I/c;w_last = zeros(M,1);  endd = Signal_noise(i);                         %输入新的期望信号x = [sin(2*pi*F4*(i-1)/Fs)cos(2*pi*F4*(i-1)/Fs)];                 %输入新的信号矢量%算法正体K = (P_last * x)/(lamda + x'* P_last * x);   %计算增益矢量y = x'* w_last;                          %计算FIR滤波器输出Eta = d - y;                             %计算估计的误差w = w_last + K * Eta;                    %计算滤波器系数矢量P = (I - K * x')* P_last/lamda;          %计算误差相关矩阵%变量更替P_last = P;w_last = w;%滤波结果存储y_out(i) = y;Eta_out(i) = Eta;w_out(i,:) = w';
end
%%
figure;
subplot(3,1,1);
plot(t,Signal);
title('原始信号');
xlabel('时间t/s');
subplot(3,1,2);
plot(t,Signal_noise);
string = ['加入50Hz工频干扰的信号,信干比SIR = ',num2str(SIR),'dB'];
title(string);
xlabel('时间t/s');
subplot(3,1,3);
plot(t,Eta_out,'b',t,Signal,'r');
title('输出误差');
xlabel('时间t/s');
axis([0,3,-2*10^-5,2*10^-5]);%
运行一下得到如下的仿真结果:

可以看到仿真的结果相比于LMS的要好一些。

实际项目运用情况简介

        心电信号(ECG 10mV以下)以及脑电信号(EEG 100uV以下)都是非常微弱的信号,其频带在0.1Hz到80Hz之间,在采集的过程中周围的各种50Hz工频干扰及其倍频三倍频等干扰会通过大地,空气等介质传播到人体上,进而被采集进来形成干扰。其强度一般是远大于心电信号的,所以要进行后一步详细的分析,干扰必须要被滤除掉。这时利用自适应陷波器是最为有效的方法。

        当然这时用的自适应陷波器和之前介绍的又有所区别,主要区别是现在要去除的干扰频率有三个,所以需要对上述的滤波器进行改进,一种方法是采用串行的方式滤除,即首先滤除50Hz的干扰,然后滤除100Hz的,最后滤除150Hz的。另一种是采用并行的方式同时滤除这三种干扰,下面我给出的是这种方式的结构图:


下面给出的是采集的一段心电信号处理的结果:


        可以看到原始信号中的50Hz干扰非常强,如果做频谱分析的话会发现还有100Hz和150Hz的干扰因此我设计的是滤除50Hz、100Hz和150Hz的自适应陷波器,这时出来的结果已经是把50Hz、100Hz和150Hz的干扰滤除干净了但是波形视乎还是不够平滑,这主要是大于100Hz的噪声引起的,因此自适应陷波后还要将其通过一个截止频率为80Hz的LPF,也就是低通滤波器,这时的输出就相当平滑了,但是还有一个值比较大的近乎直流的浮动的电压,这个电压主要是人体的静电引起的,因此还需要估计一下这个浮动的电压,然后将其减掉从而最终得到了干净的心电信号。

        之前学习自适应一直是做的仿真,这次终于把它运用到了实际的项目中,效果非常显著,更有说服力了。如果大家有什么疑问的可以联系我,我们一起探讨。










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

相关文章

自适应滤波器及LMS自适应算法的理解

分享一篇以前写现代信号处理的课程论文。 ————————————————————

自适应中值滤波器和自适应局部(均值)滤波器的设计 python+matlab各实现

要求是:自适应中值滤波器和自适应均值滤波器的设计,分别使用python和matlab去实现 一.原理 1.自适应中值滤波器 2.自适应局部滤波器,也叫自适应均值滤波器 二.设计流程 1.自适应中值滤波器 ①生成椒盐噪声 利用rand()函数生成[0,1]的随…

自适应滤波去噪

自适应滤波器具有在未知环境下良好的运作并跟踪输入统计量随时间变化的能力。尽管对于不同的应用有不同的实现结构,但是他们都有一个基本的特征:输入向量X(n)和期望响应d(n)被用来计算估计误差e(n),即e(n)d(n)-X(n),并利用此误差信…

自适应滤波(LMS,RLS)

1.背景及相关知识介绍 自适应滤波存在于信号处理、控制、图像处理等许多不同领域,它是一种智能更有针对性的滤波方法,通常用于去噪。 图中x(j)表示 j 时刻的输入信号值,y(j)表示 j 时刻的输出信…

自适应滤波

自适应阵列处理是一种空间滤波技术,它包含空间阵列和自通应处理两个部分。根据空时等效性原理,从理论上来讲,时域的各种统计自适应信号处理技术均可应用于空域的自适应阵列处理 自适应滤波已在时域处理中广为应用,其实现可以来用…

matlab编程实现自适应均值滤波和自适应中值滤波

matlab编程实现自适应滤波器 一、自适应均值滤波器1. 原理部分:2. 程序代码3. 结果对比 二、自适应中值滤波1. 原理部分2.程序代码3. 结果对比 一、自适应均值滤波器 1. 原理部分: 加入噪声: 原理: 将图片灰度化,然后…

自适应滤波器之横向滤波器

本文对横向滤波器作以介绍,如有表述不当之处欢迎批评指正。欢迎任何形式的转载,但请务必注明出处。 目录 1. 横向滤波器1.1. 概念1.2. 举例 2. 参考文献 1. 横向滤波器 1.1. 概念 横向滤波器(transversal filter),也…

自适应中值滤波及实现

前言 无意中看到了一篇比较老的论文,Adaptive median filters: new algorithms and results。感兴趣的可以下载下来看看。主要就是提出了一种自适应中值滤波算法,这个算法是很经典的中值滤波算法的改进版本,自动选择滤波器的大小&#xff0c…

浅谈自适应滤波器

在通常的滤波场合中,从频域的角度进行滤波,其相关的理论已经相当的成熟,只要给出相应的设计指标就可以很方便的设计出满足要求的滤波器。然而在更一般的情况下,人们所需要的滤波器工作的环境是时变的,这就导致事先已经…

自适应滤波原理

在网上,看到一篇不错的自适应滤波原理讲解的文章,原文网址为:自适应滤波原理简介 全文包括: 1. 自适应滤波器简介 2. 自适应干扰抵消原理 3. 自适应滤波原理 4. 最小均方(LMS)算法 5. Matlab实现 一、自适…

自适应滤波算法综述

我要讲的几种方法 绪论自适应滤波的基本原理自适应滤波算法自适应滤波算法种类最小均方误差算法(LMS)递推最小二乘算法(RLS)变换域自适应滤波算法仿射投影算法其他 自适应滤波算法性能评价 自适应滤波的Matlab仿真正弦信号加噪的L…

Java反射机制你还不会?那你怎么看Spring源码

文章目录 1.Java代码在计算机中经历的阶段:三个阶段2.Java识别类和对象信息的两种方式3.什么是反射4.获取Class对象的方式5.Class对象的功能6.通过反射操作类中的成员变量、构造函数、方法7.案例8.反射的优缺点 1.Java代码在计算机中经历的阶段:三个阶段…

Java 反射 理解

Java 反射 定义 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。 简…

Java反射机制的原理和用途

看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依据自己的理解去阐述什么是Java的反射机制,反射用在什么地方,以及怎么来使用? 开篇前,我们还是要了…

Java反射详解及作用

参考视频链接: 哔哩哔哩视频. 1. 反射概述 能够分析类能力的程序叫做反射(reflective),对于任何一个Class类,反射可以在运行时直接得到这个类的全部成分,包括构造器,成员方法,成员变量。获得的构造器对象为Construct…

JAVA反射机制分析-------spring的通过反射创建bean实例对象以及属性注入的原理解析

JAVA反射机制 java反射机制是在运行状态中,对于任意一个类, 能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为JAVA语言的反射机制。 巧妙的利用ja…

【Spring】spring的反射机制详解

一、什么是反射: (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。 &…

Spring————java的反射机制,Spring的IOC和DI

一、认识Spring 1.1、Spring家族 SpringFramework: Spring框架:是Spring中最早核心的技术,也是所有其他技术及的基础。 SpringBoot:Spring是用来简化开发。而SpringBoot是来帮助Spring在简化的基础上能更快速进行开发。 SpringCloud&#xf…

分布式定时任务调度实战

目录 1、为什么需要定时任务 2、定时任务调度框架 2.1 单机 2.2 分布 3、xxl-job和elastic-job对比 3.1 支持集群部署方式 3.2 多节点部署任务执行方式 3.3 日志可追溯 3.4 监控告警 3.5 弹性扩容缩容 3.6 支持并行调度 3.7 高可用策略 3.8 失败处理策略 3.9 动态…

浅谈传统定时任务和分布式定时任务

为什么用定时任务? 定时任务平台可以在后台自动检测数据并进行操作。主要应用在订单状态改变、后台统计、定时发送邮件或短信等。 定时任务怎么部署实现? 传统的定时任务可以通过可定时线程池、timertask、quartz、spring-schedule方式来进行处理。他…