【问题标题】:Using a low pass filter to calculate average?使用低通滤波器计算平均值?
【发布时间】:2017-09-10 17:07:37
【问题描述】:

如果我想计算 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,而不是直接对输出数组进行操作。

【问题讨论】:

  • 函数中的 alpha 是什么?
  • 我的意思是,这不是经典的平均操作,不是吗?
  • @magicleon 看起来像一个指数加权移动平均线。

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


【解决方案1】:

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

一般来说:

低通滤波器是使具有一定频率的信号通过的滤波器 低于某个截止频率并衰减信号 频率高于截止频率。

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

【讨论】:

  • 移动平均线只是低通滤波器的一个特例。
  • 一个低通滤波器削减了高频,是的。本质上,它对应于平均,因为您消除了信号的高度变化。在图像处理中也可以看到一个例子,其中模糊是一个平均过程,它对应于频率上的低通滤波。
  • @magicleon,是的,它会削减高频,但不会削减较低的值,而平均值更像是 2 个滤波器组合 - 一个低通和一个高通 - 以获得中心附近的范围(平均)
  • output[] 在执行第一次过滤迭代之前被初始化为input[] 的第一个值。但即使它被初始化为0,它也不会停留在0,因为output[] 将在第一次过滤迭代中被分配(1-alpha)*input[i]...此外,the page you're quoting 还声明 “低通滤波器 [...] 通常用于清理信号、去除噪声、执行数据平均 [...]”
  • @ACV - 一般来说,移动平均线不是高通滤波器(也不是带通滤波器)。
【解决方案2】:

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

警告:数学提前

为了将算术平均值与您使用的一阶递归低通滤波器进行比较,让我们从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,输出方差主要受用于初始化的第一个样本的方差支配。这在以下输出方差(由输入方差归一化)的比较图中尤为明显:

因此,要么在将 previousOutput 初始化为零时得到估计均值的偏差,要么在使用第一个样本进行初始化时得到较大的残差方差(远大于算术平均值计算)。

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

【讨论】:

  • 谢谢,但是我认为你误解了我的实现。数组和 for 循环就在那里,因为我的数据来自 3 轴加速度计,所以它由 float[3]{ X, Y, Z } 组成。我已经更新了问题中的代码以使其更清晰。
  • 啊,这更有意义。性能分析和相应的结论仍然应该适用。
猜你喜欢
  • 2014-10-24
  • 2015-01-03
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
相关资源
最近更新 更多