我的原始信号图如下。
我打算做的是做“真正的峰值”检测。也就是说,不应计算原始信号中的锯齿状噪声峰值。
在 Python 中实现 Chebyshev Type 2 LPF 之后,信号被平滑成下图。
可以看出,我可以在 Python 中实现 LPF。
但我的问题是用Java实现它。
有没有适合我目的的现成 LPF?或者任何人都可以教我如何在 Java 中做到这一点?
参数如下:
截止频率 = 4赫兹。采样率 = 350Hz。
我的原始信号图如下。
我打算做的是做“真正的峰值”检测。也就是说,不应计算原始信号中的锯齿状噪声峰值。
在 Python 中实现 Chebyshev Type 2 LPF 之后,信号被平滑成下图。
可以看出,我可以在 Python 中实现 LPF。
但我的问题是用Java实现它。
有没有适合我目的的现成 LPF?或者任何人都可以教我如何在 Java 中做到这一点?
参数如下:
截止频率 = 4赫兹。采样率 = 350Hz。
有很多方法可以实现这样的过滤器。直接形式 I既简单又数值稳定,所以我会推荐它。我将显示递归变量的双精度数字以确保准确性。你可能想到处使用双打来避免转换,但我会用 float 和 double 显示,这样你就可以看到你真正需要双打的地方。
对于这样的高阶过滤器,我没有方便的代码,因此未经测试,但此处的概念和上面的链接将为您提供答案。您始终可以将结果与 python 结果进行比较。
首先,您应该已经具有以下形式的系数:
float a[10] = { ... }
float b[10] = { ... }
现在,您需要确保系数已标准化(如果尚未标准化):
for( int i=0; i<10; ++i )
b[i] /= a[0];
for( int i=1; i<10; ++i )
a[i] /= a[0];
您的最后一个设置步骤是创建内存缓冲区来存储旧输入 (x) 和输出 (y):
float x[10] = { 0, 0, 0, ... }
double y[10] = { 0, 0, 0, ... }
在为新数据集“重置”过滤器时,请记住再次将这些值设置为 0。
现在您可以开始处理了。这涉及两个步骤:1. 计算您的输出,以及 2. 更新您存储的值。
float processOneValue( float in ) {
// calculate new output:
double out = in * b[0] ;
for( int i=0; i<9; ++i )
out += x[i]*b[i+1] ;
for( int i=0; i<9; ++i )
out -= y[i]*a[i+1] ;
// update:
for( int i=9; i>=1; --i )
y[i] = y[i-1];
y[0] = out;
for( int i=9; i>=1; --i )
x[i] = x[i-1];
x[0] = in;
return out;
}
由于这是一个如此高阶的过滤器,使用环形缓冲区可能比我用于 x 和 y 的“bucket-brigade”样式更新更有效,但这很有效并且更易于阅读。
现在,要处理一组数据,只需循环 processOneValue()。您可以就地或在新数组中获取输出。