Savitzky-Golay 滤波器在心电数据平滑中的应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012284960/article/details/73699582

  大二的时候做过一个三导联心电的项目,采用的处理器是STM32。当时在中文网站很少存在关于这方面的资料,特别是心电数据平滑这一块。之前在国内某一论坛上分享了一下作品以及作品的全部资源,但是大部分的人对心电数据平滑存在着很大的疑惑。于是今天想总结一下,写一个关于SG滤波器的推导。
  首先,我们对 N 个数据 x[n](n[M,M],N=2M+1) ,用( K+1 )项多项式进行近似

pnx[n]

其中 pn 表示平滑之后的数据,表示为
pn=k=0Kaknk

那么我们就得到了这样的一个表述,我们用 p 来代替 x p 表示对 x 平滑之后的数据
p=k=0Kak(M)kk=0Kak(1M)kk=0Kak(M)kxMx1MxM=x

这个问题的关键就是求解出系数 ak(k=0,,K) 。既然是近似,那么就存在误差,我们用均方误差来衡量估计的性能,即
MSE=n=MM(p[n]x[n])2=n=MM[k=0Kaknkx[n]]2

由于目标函数是关于系数 ai 的凸函数,因此系数的值在驻点取得
MSEai=n=MM[ni(k=0Kaknkx[n])]=0n=MMnik=0Kaknk=n=MMnix[n]


A=(M)0(1M)0(M)0(M)1(1M)1(M)1(M)K(1M)K(M)K,a=a0a1aK

用矩阵来表示公式(6)如下
AT:iAa=AT:ix

其中 A:,i 表示矩阵 A 中的第 i 列全部元素组成的列向量。那么由公式(8)我们知道
Aa=x

根据最小二乘法,方程解为
a=Ax

其中 A 表示 A 的Moore-Penrose逆矩阵,这也就是为什么SG滤波器称为最小二乘平滑的原因,因为求解方程组用了最小二乘法。最终我们得到
a=(ATA)1ATx

现在已经得到了系数 a ,接下来就是求 p
p=k=0Kak(M)kk=0Kak(1M)kk=0Kak(M)k=(M)0(1M)0(M)0(M)1(1M)1(M)1(M)K(1M)K(M)Ka0a1aK=Aa

因此,最后的表达式是
p=Aa=A(ATA)1ATx

Matlab处理心电信号
======================构造SG滤波器======================

N=11;
d=3;
M=(N-1)/2;

for m=-M:M
    for i=0:d
        S(m+M+1,i+1)=m^i;
    end
end

F=S'*S;
B=S*F^(-1)*S';

代码中的 S 矩阵就是本文中的 A ,代码中的 F 就是 (ATA)1 ,代码中的矩阵 B 就是 A(ATA)1AT .

======================处理原始数据部分======================

for i=1:M+1
    y(i,1)=B(:,i)'*A(1:N);
end

for n=M+2:L-M-1
    y(n,1)=B(:,M+1)'*A(n-M:n+M);
end

for i=0:M
    y(L-M+i,1)=B(:,M+1+i)'*A(L-N+1:L);
end

Question 1: 为什么对长序列A的处理分三部分?

代码中的A表示待处理的长序列,对于A的第一个元素,该元素的左边是没有元素的,对于第M+1个元素,它的左边刚好有M个元素,由于我们处理的时候,是以当前处理的数据为中心数据,然后左右两边各有M各元素。因此长序列A中,前M+1个元素,和后M+1个元素的处理方法和中间的处理方法是不一样的,具体体现在代码中如下
======================处理前M+1个元素=====================

for i=1:M+1
    y(i,1)=B(:,i)'*A(1:N);
end

=======================处理中间的元素======================

for n=M+2:L-M-1
    y(n,1)=B(:,M+1)'*A(n-M:n+M);
end

=====================处理末尾的M+1个元素====================

for i=0:M
    y(L-M+i,1)=B(:,M+1+i)'*A(L-N+1:L);
end

处理前面和末尾的两部分数据我们可以理解,但是中间的数据,为什么仅仅选取B矩阵的第M+1列呢?其实不难发现,矩阵 B 是对称矩阵,并且该矩阵的每一列元素的和为1,而矩阵 B 第M+1列,中间最大,依次往两边递减
比如N=11,d=4时


-0.0839 0.0210 0.1026 0.1608 0.1958 0.2075 0.1958 0.1608 0.1026 0.0210 -0.0839

我们再来看看数据平滑的策略,我们处理第 i 个元素,需要前 M 个元素,和后 M 个元素。很显然,当前元素的比重应该最大,往两边逐个递减。而满足此条件的,只有 B 矩阵中的中间列。

Question 2:为什么三部分的处理的系数都是对 B 矩阵的某一列的转置如B(:,i)’,B(:,M+1)’,B(:,M+1+i)’,而理论部分推导为 p=Bx ? 理论部分是行向量,而不是列向量的转置



这里主要是 B 是对称矩阵,行向量和列向量转置是相等的。
应用SG滤波器的前后效果如下:



附录,SG滤波器处理心电信号

clc;
clear all;
A=importdata('mit.txt') ;
figure
subplot(211)
plot(A);
title('数据库数据')

% 构造滤波器
N=11;
d=3;
M=(N-1)/2;

for m=-M:M
    for i=0:d
        S(m+M+1,i+1)=m^i;
    end
end
F=S'*S;
B=S*F^(-1)*S';


% 心电信号通过滤波器
[L,L1]=size(A);
for i=1:M+1
    y(i,1)=B(:,i)'*A(1:N);
end

for n=M+2:L-M-1
    y(n,1)=B(:,M+1)'*A(n-M:n+M);
end

for i=0:M
    y(L-M+i,1)=B(:,M+1+i)'*A(L-N+1:L);
end
subplot(212)
plot(y);
title('S-G平滑滤波之后数据')

在这个网址中可以下载全部的心电资料
http://www.cirmall.com/circuit/2179/%E5%88%86%E4%BA%AB%E5%9F%BA%E4%BA%8ESTM32%E7%9A%84%E5%BF%83%E7%94%B5%E9%87%87%E9%9B%86%E7%B3%BB%E7%BB%9F%EF%BC%88%E7%A1%AC%E4%BB%B6%2B%E8%BD%AF%E4%BB%B6%2B%E4%B8%8A%E4%BD%8D%E6%9C%BA%2B%E8%AE%BE%E8%AE%A1%E6%8A%A5%E5%91%8A%E7%AD%89%EF%BC%89#/details

猜你喜欢

转载自blog.csdn.net/u012284960/article/details/73699582