java - 如何用Java实现Chebyshev Type 2 LPF?

标签 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 做到这一点?

参数如下:

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

最佳答案

有多种方法可以实现这样的过滤器。 Direct Form I既简单又数值稳定,所以我推荐这样做。我将显示递归变量的 double 字以确保准确性。您可能想在各处使用 double 以避免转换,但我将使用 float 和 double 进行显示,以便您可以看到哪里真正需要 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() 即可。您可以就地或在新数组中获取输出。

关于java - 如何用Java实现Chebyshev Type 2 LPF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16879642/

相关文章:

java - 关于通过名称获取 IP 地址

python - 如何从运行 pyzmq 的进程捕获 SIGERM、SIGINT?

c - 当 SIGINT 信号被忽略时打印字符串

Scientific Linux 上的 Java 安装程序显示了两个不同的版本

java - Java Eclipse 中未找到源错误

java - 将 JSONArray 转换为 JSONObject

R如何使用带有filter或filter_的curl curl?

grails - Grails如何使用过滤器进行页面登录检查

PHP MySql 电子商务左栏过滤结果

c - 如何在 ANSI C 中使用 strsignal 和 WCOREDUMP?