使用低通滤波器计算平均值?

时间:2017-04-14 12:28:40

标签: java filtering signal-processing moving-average lowpass-filter

如果我想计算平均400个数据点(来自加速计传感器的噪声值),我可以使用这样的低通功能吗?

private float lowPass(float alpha, float input, float previousOutput) {
    return alpha * previousOutput + (1 - alpha) * input;
}

我将这个比较为简单地将400个数据点存储在List<float>中,将它们相加并除以400.

即使alpha的值很高,我的结果也会大不相同。难道我做错了什么?我可以使用低通滤波器来计算平均值,还是通常更好地简单地计算“实际”平均值?

修改

我的低通功能最初使用float[]作为输入和输出,因为我的数据来自3轴加速度计。我将其更改为float并删除了内部for循环以避免混淆。这也意味着输入/输出现在作为原始值传递,因此该方法返回float而不是直接在输出数组上操作。

2 个答案:

答案 0 :(得分:0)

如果你有能力计算算术平均值(如果保持运行总和甚至不需要额外的存储空间)那么在大多数情况下,由于下面描述的原因,这可能是更好的选择。

警告:数学提前

为了将算术平均值与您使用的一阶递归低通滤波器进行比较,让我们从N个样本的信号开始,其中每个样本的值等于m加上一些方差为v的高斯噪声。让我们进一步假设噪声与样本无关。

计算此信号的算术平均值将为您提供平均m和方差v/N的随机结果。

假设第一个previousOutput被初始化为零,导出低通滤波器的最后一个输出(output[N-1])的均值和方差,我们得到一个平均m * (1 - alpha^N)和方差v * (1-alpha)^2 * (1-alpha^(2*N)) / (1 - alpha^2)。 可以看出的一个直接问题是,对于较大的m,估计平均m * (1 - alpha^N)对于真值m来说可能相当远。不幸的是,当alpha接近1时,这个问题变得更糟。这是因为过滤器没有时间提升到它的稳态值。

要避免此问题,可以考虑使用第一个输入样本初始化第一个previousOutput

在这种情况下,最后一个输出的均值和方差分别为mv * ((1-alpha)^2*(1-alpha^(2*N-2))/(1-alpha^2) + alpha^(2*N-2))。这次的问题是,对于较大的alpha,输出方差在很大程度上取决于用于初始化的第一个样本的方差。这在下面的输出方差比较图(通过输入方差归一化)中尤为明显:

enter image description here

因此,当您使用零初始化previousOutput时,您会得到估计平均值的偏差,或者在使用第一个样本进行初始化时得到大的残差方差(远远超过算术平均值计算)。 / p>

请注意,根据观察到的变化的性质,具体数据的实际性能可能会有所不同。

答案 1 :(得分:-2)

output[]是什么?如果它保存结果并使用0初始化,则该术语将始终为零:alpha * output[i]

总的来说:

  

低通滤波器是一种以频率传递信号的滤波器   低于某个截止频率并衰减信号   频率高于截止频率。

所以它不是平均值,它基本上是一个特定阈值的截止值。