大二的时候做过一个三导联心电的项目,采用的处理器是STM32。当时在中文网站很少存在关于这方面的资料,特别是心电数据平滑这一块。之前在国内某一论坛上分享了一下作品以及作品的全部资源,但是大部分的人对心电数据平滑存在着很大的疑惑。于是今天想总结一下,写一个关于SG滤波器的推导。
首先,我们对
其中
那么我们就得到了这样的一个表述,我们用
这个问题的关键就是求解出系数
由于目标函数是关于系数
设
用矩阵来表示公式(6)如下
其中
根据最小二乘法,方程解为
其中
现在已经得到了系数
因此,最后的表达式是
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';
代码中的
======================处理原始数据部分======================
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列呢?其实不难发现,矩阵
比如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
我们再来看看数据平滑的策略,我们处理第
Question 2:为什么三部分的处理的系数都是对
这里主要是
应用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平滑滤波之后数据')