资讯动态

呼吸心跳信号检测中的滤波算法:滑动平均、一阶低通与互补滤波实践

发布时间:2026/10/4 1:30:43 来源:尧图企业网站定制
从传感器拿到原始波形到最终在屏幕上稳定显示呼吸和心跳数值中间隔着最关键的一道工序滤波算法。前几篇我们聊完了传感器选型、模拟前端设计和采样策略这一篇集中把呼吸心跳信号检测里的滤波算法一次讲透重点落在滑动平均、一阶低通、互补滤波这三大类的实际应用上。先说一句大实话滤波不是把波形变好看而是把淹没在噪声里的有效频段单独拎出来。呼吸和心跳信号的频率范围是固定的呼吸一般在0.2到0.5赫兹心跳在1到1.7赫兹左右而人体运动伪迹、工频干扰、肌电噪声遍布整个频谱。滤波算法做得不好后面所有特征提取都是空中楼阁。1. 干扰成分拆解先搞懂噪声从哪来再谈怎么滤滤波算法选型不能拍脑袋第一步是搞清楚你要滤掉什么。我在实际调试中把呼吸心跳检测的干扰源分成四类每类的频谱特征和处理策略完全不一样。1.1 运动伪迹非平稳、宽频带最难对付的一类这是呼吸心跳检测的头号敌人。人体呼吸和心跳引起的体表振动幅度只有几十到几百微米而肢体稍微动一下产生的位移可能是毫米级的两者差了三个数量级。更麻烦的是运动伪迹没有固定频段走路、转身、说话产生的干扰信号可以从0.1赫兹一直延伸到几十赫兹直接和呼吸、心跳频段重叠。我在实测中发现运动伪迹的幅度往往比有效信号大5到10倍如果不做处理后续算法会把运动瞬间误判成心率骤变或呼吸暂停。对于这类干扰单靠频域滤波解决不彻底必须结合时域判断——检测到信号幅值突变时动态调整滤波器的响应速度。频域滤波负责稳态场景时域逻辑负责瞬态场景两者配合才算完整方案。1.2 工频干扰50赫兹固定频段最容易被忽视的隐藏项很多人觉得数字滤波阶段不用管工频干扰因为模拟前端已经加了陷波器。实际情况是模拟陷波器只能衰减掉80%左右的工频分量剩余部分经过放大后依然会在ADC采样结果里留下明显纹波。尤其当心电电极或者压电薄膜传感器的引线比较长时分布电容耦合进来的工频信号可能比有效信号还大。工频干扰的频谱很干净就是50赫兹基波加上少量谐波跟呼吸、心跳频段隔得很远。理论上用低通滤波器就能压掉但如果低通滤波器的衰减特性不够陡峭50赫兹处的残差还是会泄漏到高频噪声里影响后续的信号质量评估。我的处理习惯是ADC采样率设在250赫兹以上数字端再加一个截止频率20赫兹的二阶低通把残余工频彻底压死。1.3 基线漂移呼吸信号里的低频伪影压电薄膜传感器和心电电极都会遇到基线漂移的问题。呼吸运动引起的胸廓整体位移、电极与皮肤接触面的阻抗变化、环境温度缓慢波动都会让信号基线出现0.1到0.5赫兹的低频漂移。这个频段恰好和呼吸信号重叠没法用普通高通滤波器分离。处理基线漂移有两种思路一是采用中值滤波估计基线再用原始信号减去基线二是设计自适应高通滤波器截止频率随着漂移速率动态调整。我在实际项目中更推荐第一种中值滤波的窗口长度取呼吸周期的一半左右既能跟踪基线变化又不会把呼吸波峰吃掉。具体参数后面详细说。1.4 高频电子噪声ADC量化噪声与放大电路热噪声这类噪声是白噪声特性平均分布在所有频段幅值不大但会抬高信号的本底噪声。标准的心电信号幅度只有0.5到4毫伏放大一千倍之后放大器本身的输入噪声和电源纹波都会成为不可忽略的背景噪声。量化噪声则和ADC位数直接相关12位ADC的理论信噪比约74分贝16位ADC可以做到98分贝。高频噪声对呼吸心跳检测的影响不是致命的但如果后面要做R波检测或者呼吸波形分析噪声会直接影响峰值定位精度。这类噪声的处理交给低通滤波器即可属于附带清理项不像运动伪迹需要专门设计。2. 滑动平均滤波窗口长度怎么定直接决定波形失真程度滑动平均滤波是所有滤波算法里最直观的把最近N个采样点的平均值作为当前输出本质是一个FIR低通滤波器。它最大的优势是无脑、稳定、不会出现滤波器发散的问题缺点是相位延迟明显而且窗口长度选不好会导致波形严重失真。滑动平均滤波器的频率响应有个特点第一个陷波点在fFs/N处Fs为采样率这意味着如果窗口长度过大呼吸信号的高次谐波会被陷波器吃掉波形变得圆钝窗口长度过小又滤不干净高频噪声。实测中我总结出一套窗口选择公式窗口长度取目标信号周期的十分之一到五分之一比较合适。2.1 呼吸信号场景的窗口参数计算假设采样率250赫兹呼吸频率按每分钟18次计算即0.3赫兹一个呼吸周期约3.3秒对应采样点数为825个。五分之一周期就是165个采样点取整后窗口长度可以设在100到150之间。窗口太长会引入约0.5到0.7秒的延迟对呼吸暂停检测这种对时间敏感的应用来说延迟过长会拖慢报警响应。2.2 心跳信号场景与滑动平均的坑心跳频率按每分钟72次计算即1.2赫兹周期约0.83秒在250赫兹采样率下对应208个采样点。实际测试中滑动平均窗口设在20到40之间就能把高频噪声压到可接受范围。窗口超过60之后R波峰会明显变矮、变宽幅值损失可达三成以上。但这只是理论值实际操作中必须注意滑动平均对不同形态的波形会产生大不相同的失真。比如心电信号里的QRS波群是一个陡峭的双向脉冲滑动平均会把它的高频成分全部抹平幅值衰减很严重。如果你后续算法是靠幅值阈值来检测心搏的过度平滑会导致漏检。2.3 步进滑动平均的改进思路为了减少窗口长度带来的相位滞后我常用步进式滑动平均的做法——每采集到M个新采样点才计算一次平均值M比窗口长度N小得多。这样等效的平滑力度不变但输出数据率降低了计算量也减少了。代价是输出波形的有效分辨率变低对R波这种陡峭波形不利。步进式滑动平均更推荐用于呼吸信号处理呼吸波本身变化缓慢降低数据率不影响特征提取心跳信号适合用逐点滑动平均保证每个采样点都参与计算输出波形保持完整便于后续做更精细的分析。3. 一阶低通滤波呼吸信号频段分离的最优解一阶低通滤波是嵌入式系统里应用最广泛的滤波算法数学表达式简单到只差一次乘法一次加法y(n) α*x(n) (1-α)*y(n-1)。它的调参只有一个α从0到1之间取值α越大越信任当前采样值滤波越迟钝截止频率越高α越小越信任历史平滑值滤波越激进截止频率越低。一阶低通滤波器在呼吸心跳检测里的典型应用就是把呼吸信号的低频成分和心跳的高频成分分开。呼吸频段在0.2到0.5赫兹心跳频段在1到1.7赫兹两者间隔足够大用截止频率0.8赫兹的一阶低通就能把心跳成分大部分衰减掉只保留呼吸波形。3.1 截止频率与α值的换算关系α和截止频率的换算公式是α 1 - exp(-2π * fc * Ts)其中Ts是采样周期fc是期望的截止频率。以采样率100赫兹、期望截止频率0.5赫兹为例Ts 0.01秒2π * 0.5 * 0.01 0.0314exp(-0.0314) ≈ 0.969α ≈ 0.031。也就是说α取0.03左右就能实现约0.5赫兹的截止频率。我把这个公式做成了一张常用参数表方便直接对照使用。采样率Hz截止频率Hzα参考值1000.50.0311001.00.0612500.50.0132501.00.0255000.80.010注意这个换算公式依赖线性时不变系统的假设实际信号如果含有较强非线性成分用公式算出的参数还需要微调。3.2 一阶低通在呼吸信号提取中的实际调试过程我在实测中观察到α取0.03时100赫兹采样率下呼吸波形输出干净稳定但波形幅值比原始信号衰减了约15%这是因为呼吸信号的二次谐波也被一并滤掉了。如果你后续需要做呼吸波形面积分析或潮气量估算需要考虑这个幅值损失在算法里做补偿。如果α取到0.05呼吸波形的高次成分保留得更多波形看起来更“真实”但混进来的心跳干扰也会明显一些。我的做法是先用α0.03跑通流程确认呼吸暂停检测功能正常后再逐步调大α观察误判率的变化。实际工程里没有最好参数只有最适合当前场景的参数。3.3 一阶低通滤波的相位延迟特性一阶低通滤波器最被人忽略的是它的相位延迟。在截止频率附近相位延迟约45度远低于截止频率的频段延迟接近0度远高于截止频率的频段延迟接近90度。这意味着在一阶低通滤波器的输出端呼吸波形相比原始信号存在约0.3到0.5秒的时间滞后。对呼吸暂停检测来说0.5秒延迟完全能接受因为暂停持续时间通常超过10秒。但如果你的系统还承担实时显示功能建议把滤波后的波形和原始波形同时显示并标注延迟时间避免临床用户对波形实时性产生误解。4. 互补滤波运动场景下融合多传感器数据的实战方案单纯使用单一路径滤波很难同时兼顾呼吸、心跳和运动抑制。互补滤波的核心思想是用一个高通滤波器和一个低通滤波器分别处理同一路信号再把结果叠加各取所长。在呼吸心跳检测里互补滤波最常见的应用是融合加速度传感器和压电薄膜传感器的数据。压电薄膜传感器对呼吸和心跳的微小振动敏感但极易受运动干扰加速度传感器能捕捉整体姿态变化但对微小振动不敏感。互补滤波的思路很直接加速度信号经过高通滤波保留运动分量压电信号经过低通滤波保留生理振动分量加权相加后得到既保留呼吸心跳特征又抑制运动干扰的合成信号。4.1 频域分界点怎么确定互补滤波的关键在于分界频率的选取即高通和低通的交接点。理想的互补滤波器要求两个通路在分界点处的幅频响应相加等于1相位响应互相补偿。实际工程里我习惯把分界点定在0.5赫兹附近确保0.5赫兹以下的呼吸信号主要由低通通路提供0.5赫兹以上的高频信息由高通通路补充。分界频率太高运动干扰的残余会明显增多分界频率太低压电信号里有效的心跳成分会被滤掉。我建议用呼吸信号的上限频率0.5到0.6赫兹作为分界基准这样既保留完整呼吸波形又让心跳成分有足够的余量穿透高通通路。4.2 权重系数α和β的整定方法互补滤波的加权公式是输出 α * 低通输出 β * 高通输出且α β 1。α取接近1时更信任压电信号β取接近1时更信任加速度信号。实际整定时我采用两步法先做静态测试让被测者保持平静呼吸调整α让波形最平滑再做动态测试让被测者做小幅动作找出运动抑制最好但呼吸波不塌陷的α范围。一组实测数据供参考采样率100赫兹分界频率0.5赫兹α取0.7、β取0.3时平静状态下呼吸波形清晰走路时运动伪迹抑制了约75%。α取0.9时平静状态下波形更好看但走路时波形完全被运动干扰覆盖。α取0.5时恰好相反运动抑制不错但呼吸波形细节丢失较多。4.3 互补滤波与卡尔曼滤波的边界很多开发者会问为什么不用卡尔曼滤波卡尔曼滤波在多传感器融合里确实强大但它对系统模型和噪声协方差矩阵的设定高度敏感调参复杂计算量也大。在一颗主频72MHz的Cortex-M3单片机上一阶互补滤波每次迭代只消耗2次乘法和1次加法几百字节内存卡尔曼滤波要涉及矩阵运算开销至少高一个数量级。如果产品是电池供电的便携式设备或者MCU主频在48MHz以下我优先推荐互补滤波。如果系统跑在手机或树莓派级别处理器性能充足且需要应对复杂多变的运动场景卡尔曼滤波才具备实际优势。5. 滤波参数调试链路从原始波形到干净信号的最短路程前面讲了算法原理现在说说我在实际调试设备时走通的完整链路。一套可复现的调试流程能帮你少走至少两周的弯路。5.1 第一步用频谱分析确认干扰成分拿到原始信号后不要急着滤波先做FFT频谱分析。我习惯把ADC采样数据以每段1024个点做FFT看三个关键频段0.1到0.5赫兹是否有异常峰值1到2赫兹是否能看到心跳峰50赫兹附近是否残留工频。这一步能直接告诉你滤波器的设计目标避免闭着眼睛调参数。实测中遇到过一个典型情况频谱上呼吸峰旁边出现一个紧挨着的旁瓣频率只相差0.05赫兹开始以为是呼吸节律波动后来发现是空调气流引起的传感器温度漂移。这类干扰靠普通滤波器完全滤不掉最终通过在传感器周围加了一层隔热棉解决。滤波算法不是万能的有些干扰要从物理层面消掉。5.2 第二步先粗调低通再精调截止频率频谱看清之后按照下面三个优先级依次调整滤波链第一优先级先用一阶低通滤除1赫兹以上的高频噪声确认心跳成分被明显衰减呼吸波形轮廓清晰。第二优先级用中值滤波处理基线漂移窗口长度取10到20个采样点观察基线是否回归平稳。第三优先级加入带通滤波压制工频干扰及其谐波。带通滤波器的品质因数Q不要超过10Q值太高会导致共振峰附近的波形畸变。每一步调整后都记录波形截图和参数值形成参数-波形对照表。调试最忌讳一次性调完三个滤波器出问题根本不知道是哪个环节引入的。5.3 第三步时域验证与指标量化滤波效果的评判不能靠“看起来不错”要有量化指标。我用刚说的三个指标评估滤波质量信噪比滤波后信号的有效值除以噪声底的有效值期望提高至少10分贝峰峰值保持率滤波后呼吸波峰峰值除以原始波形峰峰值期望在70%到90%之间过零率稳定性滤波后呼吸波过零率的变异系数期望小于10%。一次典型的调试过程记录如下原始波形信噪比8分贝峰峰值保持率100%过零率变异系数23%。经过滑动平均加一阶低通后信噪比提升到21分贝峰峰值保持率降到82%过零率变异系数降到6%。这个结果说明滤波链有效且失真在可接受范围。6. 各滤波算法实测效果对比与选型建议不同滤波算法在呼吸心跳检测中的表现差异很大我把实测过的方案整理成一张对比表方便对照选型。算法计算开销相位延迟运动抑制能力适合场景主要缺点滑动平均极低中等差延迟5到10个窗口周期稳态呼吸监测窗口长度敏感波形变形一阶低通极低中低差无运动判断逻辑呼吸信号频段分离相位延迟随截止频率变化互补滤波低低强适合动态场景可穿戴多传感器设备需要加速度传感器辅助中值滤波低低中对基线漂移有效基线校正、去毛刺对连续运动伪迹无效卡尔曼滤波中高低强自适应能力好高性能处理器调参复杂模型依赖强6.1 静态场景推荐躺姿或坐姿的静态监测场景压电薄膜或心电电极的信号质量本身就不差运动干扰很少。推荐滑动加一阶低通的组合方案计算量最小代码简单稳定可靠。呼吸检测用一阶低通截止频率0.5赫兹心跳部分可以在滑动平均后加一个截止频率1赫兹的高通滤波进一步压掉呼吸基波。这个组合方案在做睡眠监测时表现很好整晚数据几乎不需要人工干预。唯一要留意的后半夜翻身造成的信号突变可以加一段按幅值自动增益控制的代码信号幅度超过阈值时自动缩放防止波形削顶。6.2 动态场景推荐走路、慢跑等动态场景强烈建议用互补滤波融合加速度计数据。压电薄膜贴附位置可选胸骨左缘第二到第五肋间加速度计随设备一起固定在胸带中。实测在跑步机上4公里每小时的速度下互补滤波方案依然能提取出可靠的呼吸频率误差控制在3次每分以内单靠一阶低通方案在同场景下误差达到8次每分以上。6.3 多级级联的工程落地建议如果你的系统需要同时输出呼吸率和心率两个指标建议把滤波链路拆成两条独立通路而不是用一条链路硬扛两个频段呼吸通路一阶低通0.5赫兹- 中值滤波窗口50个点- 下采样到20赫兹 - 峰值检测心跳通路带通滤波1到18赫兹- 滑动平均窗口5个点- 峰值检测 - RR间期计算两条通路可以并行处理互不干扰。我最早把两个信号揉在一条通路里处理结果呼吸波峰识别总是被心跳干扰影响改了三天都没找到原因拆成两条通路后问题彻底消失逻辑也清晰了很多。7. 滤波效果验证该用什么指标衡量滤波是否到位滤波调得好不好不能只靠眼睛看。对比滤波前后的指标有四个最实用的维度。7.1 频域对比法把滤波前后的信号各做一次FFT对比频谱包络的变化。理想情况是目标频段0.2到1.7赫兹的幅度基本不降或下降不超过3分贝干扰频段运动伪迹区的幅度衰减至少20分贝。实测中很多滤波后波形看着很干净但频谱上1到2赫兹的整个区域都塌陷了这说明截止频率选得过低把有效信号也滤掉了一部分。遇到这种情况不要急着调截止频率先算一下你的目标频段和干扰频段的间隔有多少。间隔越大滤波器设计的自由度越高截止频率选择的容错空间越大。7.2 时间滞后评估测量滤波后波形相对原始波形的过零偏移估算延迟时间。滑动平均的延迟约为(N-1)/2个采样周期一阶低通的延迟约在1/4到1/2个截止频率周期之间。叠加多个滤波器时延迟是逐级累加的最终延迟超过一个呼吸周期约3秒的话实时显示就会明显跟不上真实节律。工程上有个简单做法在传感器旁边放一个参考呼吸带同步记录参考设备和待测设备的呼吸波形测量两位波形上升沿的时间差。这个时间差就是整个处理链路的端到端延迟。延迟小于0.5秒基本无感超过1秒就需要注意了。7.3 鲁棒性测试方法调参过程中最容易犯的错误是过度拟合某一段数据。我的做法是让三个不同体型、不同呼吸习惯的测试者各戴上设备采集五分钟信号交叉验证参数。第一轮让参数在测试者A的数据上表现好第二轮看B和C的表现再微调。经过三轮交叉调整参数基本就稳定了。这里有个关键细节滤波参数的确认一定要在目标场景的极端条件下验证。比如做睡眠监测一定要让测试者侧卧、趴着、翻身各测一段时间如果只在仰卧位调好了参数遇到翻身动作很大概率直接翻车。8. 实测中容易踩的坑与排查建议这节都是我从实际项目里掉过的坑写下来帮大家节省排查时间。8.1 滑动平均窗口与ADC采样率不匹配这个坑我踩得最深。最初在250赫兹采样率下调试呼吸波形滑动平均窗口定在120效果很好。后来为了降低功耗把采样率降到50赫兹却忘了同步修改窗口长度。结果呼吸波形完全看不出形状跨度长达2.4秒的窗口把呼吸波峰和波谷一起抹平了。排查方法很简单把采样率、窗口长度和预期呼吸频率代入计算确认窗口对应的时间长度不要超过呼吸周期的三分之一。采样率改变时所有滤波器参数必须同步重新计算不能只改采样率。8.2 一阶低通截止频率调成呼吸谐波共振点一阶低通滤波器本身不会共振但它和二阶级联后可能出现谐振峰值。我遇到过一阶低通截止0.5赫兹串联二阶低通截止5赫兹时在2.8赫兹处出现一个3分贝的增益峰恰好落在心跳谐波附近导致输出的呼吸波形上叠加了细密的心跳纹路。排查这类问题需要用扫频信号测试滤波器链路输入0.1到10赫兹扫频信号记录输出幅频特性曲线检查是否存在预期外的增益峰。一旦发现谐振峰调整其中一级滤波器的截止频率或者减小二阶滤波器的Q值。8.3 固定截止频率滤波器无法适应呼吸骤变呼吸频率在剧烈运动后可能从0.2赫兹跃升到0.8赫兹固定的截止频率会顾此失彼。截止频率设在0.5赫兹时运动后0.8赫兹的呼吸信号会被明显衰减调到0.9赫兹时静息状态下会混入过多心跳干扰。我现在做动态场景都改用自适应策略每两秒估计一次信号的主频动态调整低通截止频率。具体做法是用滑动FFT估算当前频谱峰值所在频段滤波截止频率跟随这个频段上下浮动变化幅度限制在±20%以内防止截止频率跳变太剧烈导致输出波形抖动。8.4 实测波形表现正常但特征提取失败的隐蔽原因滤波参数没问题频谱也正常但后面峰值检测就是不稳定。排查到最后发现是数据类型的锅AD采集值是16位整数滤波计算用了浮点数输出的结果直接截断成整数累次截断误差导致波形每几百个点出现一次阶梯跳变峰值检测定位漂移。这个问题的处理很简单滤波计算使用浮点型输出时做四舍五入而不是截断或者用高精度定点数保存中间计算结果。类似的隐蔽问题还包括滤波缓冲区忘记做环形处理导致数组越界、多路传感器共用一个滤波缓冲区导致数据互相覆盖。9. 滤波参数自动标定思路最后一个进阶话题——如何让滤波参数自适应不同用户、不同佩戴位置。手动调参在样品阶段没问题产品化之后用户千差万别手动调参根本不现实。9.1 基于信号能量分布的自动标定开机后先让用户保持静息状态10秒采集一段原始信号计算0.2到0.5赫兹与0.5到2赫兹两个频段的能量比。能量比高的说明当前信号以呼吸为主低通截止频率可以适当调低抑制心跳能量比低于某个阈值时说明当前信号含大量高频成分截止频率需要调高保留心跳信息。这一步能在上电后两秒内完成粗标定精度足够应付大多数场景。如果后续检测到用户状态发生剧烈变化可以周期性地重新执行标定过程但要注意避免标定过程本身占用过多CPU时间。9.2 佩戴位置变化的自适应补偿压电薄膜贴在胸口和贴在腹部时信号特征完全不同胸口位置呼吸信号偏弱但心跳信号更清晰腹部位置正好相反。同一个滤波参数不可能同时适配两个位置。自适应方案是实时统计信号中呼吸频段和心跳频段的能量比值当这个比值出现过大的突变时自动从预设的“胸口参数组”切换到“腹部参数组”。实测中这个方法的识别准确率在九成以上误判主要出现在翻身等导致传感器移位的场景这类情况本来就难以避免。关于滤波算法的实操经验就说这么多。最后分享一个小技巧每次调整滤波参数前先在原数据上跑一遍完整流程并保存波形截图改动参数后再跑一遍两张图并排对比效率比对着代码研究高得多。调试滤波算法本质上是和信号特征打交道多积累几组参数和波形对照的经验后面做新项目时基本能一次调到位。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑