如何在Java中实现Chebyshev Type 2 LPF?

时间:2013-06-02 03:58:54

标签: java filter signals signal-processing lowpass-filter

我的原始信号图如下。

我打算做的是进行“真正的峰值”检测。也就是说,原始信号中的锯齿状噪声峰值不应计算在内。 enter image description here

在Python中实现Chebyshev Type 2 LPF后,信号将平滑到下图中。 enter image description here

可以看出,我可以在Python中实现LPF。

但我的问题是用Java实现它。

是否有适合我目的的易于建造的LPF? 或者任何人都可以教我如何用Java做到这一点?

参数如下:

截止频率= 4Hz。 采样率= 350Hz。

1 个答案:

答案 0 :(得分:1)

有很多方法可以实现这样的过滤器。 Direct Form I既简单又数值稳定,所以我建议这样做。我将为递归变量显示双精度数字以确保准确性。你可能想要四处使用双打以避免转换,但我会用浮点数和双精度显示,这样你就可以看到你真正需要双打的位置。

我没有像这样的高阶过滤器的代码,所以这是未经测试的,但是这里的概念和上面的链接将为您提供答案。您始终可以将结果与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()上循环。您可以在适当的位置或新阵列中获取输出。