直流部分隔离

DC part isolation

我的信号由快速振荡的交流部分和缓慢变化的直流部分组成。我需要计算它的 DC 部分(和包络,但现在这并不重要)。
我可以使用 STFT,过滤并将其转换回来,但它的效率有点低,因为我不是在寻找整个频谱。还有其他想法吗?
我已经阅读了 MathWorks 上的文章,我的数学足以设计一些一般和复杂的东西,但我正在寻找 技巧、提示或聪明而优雅的简单解决方案 。提前致谢!

直流隔离基本上就是低通滤波。您想要移除所有高频分量,同时保留低频分量。有很多方法可以解决这个问题,但看起来您正在寻找快速简单的方法。

最简单的低通滤波器形式之一是移动平均线。它在频域上很混乱,但对于许多简单的应用程序来说已经足够好了,实现起来很简单,而且速度非常快。

由于我稍后会谈到的原因,当您考虑频域时,它实际上并不是一个非常好的低通滤波器,但它在时域中是一个非常好的平滑滤波器,这就是听起来你需要。

更新: 发布后,我意识到这是用 MATLAB 标签询问的,而不仅仅是信号处理。我在最后添加了一些内容,展示了在 MATLAB 中执行此操作的最简单方法。

移动平均过滤器

参数:

  • N:滤波器阶数,要平均的样本数

输入:

  • xt:输入时间为t。对于负 t 假设 x 为零。

输出:

  • yt:输出时间为t。这是之前 N 个样本的平均值。

算法

初始化(t = 0)

y0 = x0 /N

在每个时间步 (t > 0)

yt = *yt-1 + ( xt - xt-N ) / N

滤波器频率响应

滤波器的脉冲响应是滤波器阶数宽度的矩形脉冲。这给出了一个简单的频率响应:

H[f] = | sin(πfN) / (Nsin(πf)) |

这表明频率响应有多糟糕,但对于许多平滑应用程序来说,这并不重要。需要注意的关键是第一个零出现在 f = 1/N。这使您可以很好地了解使用什么阶数的滤波器来平滑高于特定频率的分量,如下一节所述。

参数选择

给定采样率fs和截止频率fc,归一化截止频率就是f = fc / fs。这加上上面的频率响应,提供了一种得出滤波器阶数的简单方法,尽管手动稍微调整它可能会改善结果:

N = 1/f = fs / fc

阅读此公式的另一种方式是,重要的是滤波器阶数小于您希望保留的最快 DC 特征。否则会被部分过滤掉。

时域响应

为了说明时域响应,我将通过一些示例来说明。我将使用 fs = 1000.

的采样率

我生成了一个添加了噪声的 40 毫秒矩形脉冲,以演示增加滤波器阶数的效果。

如您所见,增加滤波器阶数可以消除噪声,但它还有其他效果。更高的订单意味着更长的延迟,以及对阶跃变化的更慢响应。一旦订单太高,结果就毫无价值。 N = 51 示例显示了当过滤器顺序比您要捕获的事件宽时会发生什么。

虽然那些倾斜的边缘可能看起来很糟糕,但对于给定的降噪量,移动平均滤波器实际上给出了最陡峭的边缘,这对于相同阶数的线性滤波器来说是可能的,并且由于算法非常简单,它也是实现最快的线性滤波器。因为它只有一个参数,所以调整起来也很简单,可以为您的应用程序找到最佳顺序。

其他调整和实施技巧

多通滤波器 改善频域中移动平均滤波器响应的最简单方法是 运行 多次通过。在几 运行s 之后,由于中心极限定理,它成为高斯滤波器的非常好的近似。这会稍微减慢阶跃响应,但也会使其圆润。更高的频率将进一步衰减,尽管它也会影响低频端的滚降。添加更多遍对性能的影响很小。

循环缓冲区 如果您正在处理数据流,那么您并不总是有一种简单的方法来查找 xt-N。通过使用循环缓冲区来跟踪最后的 N 个样本,您最终得到了一种简单的方法来查找您需要的样本,只需在算法中添加几个步骤 - 它保留了无论过滤器顺序如何,每步恒定时间。

舍入误差 如果您使用定点或整数值,则可以完全消除舍入。过滤算法中干脆不要除以N

at = *at-1 + x t - xt-N

yt = *at / N

但是,您需要注意确保这不会导致 a 中的溢出。

对于浮点值,微小的舍入误差可能会随着时间的推移而累积。 long-运行ning 过滤器的最简单解决方案是计算 y,方法是对最后 N 个样本的整个缓冲区进行平均经常。这会将您重置为没有累积错误的点,同时让您对绝大多数时间步长使用快速算法。

在 MATLAB 中实现

移动平均值是每个权重设置相同的线性 FIR 滤波器。这意味着分子都相同并且总和为1,分母为1。使用filter函数进行移动平均很简单:

y = filter(ones(1,N)/N, 1, x);

但是,这不会使用上面讨论的快速算法。如果性能是个问题,那么您需要自己实现算法。