如果我想计算平均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
而不是直接在输出数组上操作。
答案 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
。
在这种情况下,最后一个输出的均值和方差分别为m
和v * ((1-alpha)^2*(1-alpha^(2*N-2))/(1-alpha^2) + alpha^(2*N-2))
。这次的问题是,对于较大的alpha
,输出方差在很大程度上取决于用于初始化的第一个样本的方差。这在下面的输出方差比较图(通过输入方差归一化)中尤为明显:
因此,当您使用零初始化previousOutput
时,您会得到估计平均值的偏差,或者在使用第一个样本进行初始化时得到大的残差方差(远远超过算术平均值计算)。 / p>
请注意,根据观察到的变化的性质,具体数据的实际性能可能会有所不同。
答案 1 :(得分:-2)
output[]
是什么?如果它保存结果并使用0初始化,则该术语将始终为零:alpha * output[i]
总的来说:
低通滤波器是一种以频率传递信号的滤波器 低于某个截止频率并衰减信号 频率高于截止频率。
所以它不是平均值,它基本上是一个特定阈值的截止值。