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

标签 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而不是直接对输出数组进行操作。

最佳答案

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

警告:数学领先

为了将算术平均值与您正在使用的一阶递归低通滤波器进行比较,让我们从信号 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 时估计平均值出现偏差为零,或者在使用第一个样本初始化时会得到很大的残差方差(比算术平均值计算要大得多)。

最后请注意,实际性能可能会因您的特定数据而异,具体取决于观察到的变化的性质。

关于java - 使用低通滤波器来计算平均值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43411539/

相关文章:

javascript - 基于单个/全局搜索输入的切换按钮可见性为空

Php数组转MySQL查询条件结构

c - 如何针对 GPU 优化 OpenCL 内核?

audio - 8 位音频采样到 16 位

python - python中线性调频的fft振幅

java - 出现错误 : Exception in thread "main" while executing program for different loop conditions in static block

java - 十进制到二进制转换的函数不正确?

java - javafx中的ListView,添加多个单元格

java - 将节点添加到扩展场景的类中

Python:访问与循环数组的当前位置相匹配的移动窗口数组的索引