心电信号的滤波分析
前言
2020电赛器材表出来的时候,里面有一块ADC:ADS1292。根据数据手册可以知道这是一块专用测量心电信号的ADC,结合上半年的疫情,这次电赛的心电测量估计是跑不掉了。ADC只是用来测量数据的,重要的部分是对数据的分析和处理。
采集到的心电信号有许多的干扰,所以我们要对心电信号进行滤波处理,处理完成后能得到心电信号的一些在医学上有意义的信息
噪声分析
心电信号的噪声主要由以下三点:
工频干扰
工频干扰主要是由于供电网络的干扰,供电网络无处不在,工频干扰也是心电信号的主要干扰。我国用50hz交流电供电,所以这里工频干扰的主要频率为50hz,一般采用陷波滤波器实现。
肌电干扰
人体的肌肉在活动的时候会产生电信号,肌电信号的主要频率在20-5000Hz,而心电信号的主要频率在5-20Hz。一般情况下可以用低通滤波器来滤波。
基线漂移
基线漂移主要是由于人体的呼吸产生,人在呼吸的时候会使得心电信号的基准电压发生偏移,从而导致测量得到的心电信号的基准不一样,会上下浮动。虽然并不影响心电信号的特征,但是对于我们判断或者是计算机的识别来说有非常大的影响,去除基线漂移的方法有很多,高通滤波、中值滤波、小波变换等等。后面我会根据我们的需求做具体的分析,选择哪一种滤波方式。
选择滤波器
由于电赛一般只能用单片机,所以还是选用常见的FIR或者IIR滤波器。ARM官方的dsp函数非常好用,所以还是很方便的。
FIR滤波器的效果比较好,但是运算量会比较大。FIR最重要的优势是群延时是固定,在后续处理上会比较好处理。
IIR滤波器相对于FIR滤波器来说,计算量会小很多,但是由于不能确定的群延时,为了避免以后的麻烦,所以这里就没有选用。
网上还有一种用一个正向IIR一个逆向IIR组成的零延时滤波器,但是这种滤波器的实时性并不好,我们的使用场景对于实时性的要求非常的高,而且在嵌入式系统上实现比较困难,我本人对滤波器理解也没有这么深入,所以就没有考虑了。
这次我用的主控板是STM32F407ZGT,F4系列的MCU用的是M4的内核,自带FPU,加上184MHz的主频,算力还是相对充足的,所以我这里选用FIR滤波器的方式。
滤波选择
低通滤波器去除高频和工频干扰
网上大多的滤波都使用陷波滤波器和低通滤波器分别去除肌电信号和工频的干扰,但是在我的实践中,在一块单片机上用两个不同的滤波器滤波总会出现一些奇奇怪怪的问题,我也不知道是为什么,希望知道的兄弟能在评论区帮我解释一下~ 由于以上的原因,我实际的操作是用一个FIR低通滤波器实现对工频干扰和肌电信号的滤波。
中值滤波去除极限漂移
网上小波变换的方法去除基线漂移效果非常好,但是对于单片机来说的运算量有些大,而且我对小波变换理解也不是这么深入,移植程序不知道搞不搞得出来,所以就放弃了这个方案。
前面讲过了我在一个单片机中使用两个FIR滤波器滤波会有一些奇奇怪怪的问题,所以高通滤波的方案就也放弃了。
中值滤波的好处是能滤除特别明显的尖峰噪声,而我们的心率信号需要知道的特征正是“尖峰信号”,所以在中值滤波的结果是那根漂移的基线。这样我们用原始信号减去中值滤波的信号就是去除了极限漂移的心电信号了。这里需要注意的是,中值滤波的范围要选择好,因为中值滤波还是会对几个大波的幅值产生一定的影响的,需要选择合适的滤波范围才能有比较好的效果。
具体的仿真使用matlab做的。
滤波仿真
这是ads1292的原始信号,可以看到工频干扰是非常严重的。
然后用FIR的45hz低通滤波器进行滤波,可以看到数据最前面的群延时,后面的数据已经干净了许多。
这是去除群延时之后放大的效果,数据已经相对清晰了,但是也可以看到基线漂移非常严重
这是经过中值滤波的图像,极限漂移已经几乎看不见了。
具体怎么样把理论上的分析在单片机上实时实现,可以看我的这篇文章