在 android 中创建数字滤波器
creating a digital filter in android
我正在尝试处理 android 中的 ECG 信号处理。我想实现简单的数字滤波器(低通、高通)
我有一个传递函数:
这是我发现的:
wikipedia - lowpass filter - 这里看起来很简单。
for i from 1 to n
y[i] := y[i-1] + α * (x[i] - y[i-1])
但是没有关于我想使用的传递函数的任何信息。
我还找到了下面的matlab代码
%% Low Pass Filter H(z) = (1 - 2z^(-6) + z^(-12)) / (1 - 2z^(-1) + z^(-2))
b = [1 0 0 0 0 0 -2 0 0 0 0 0 1];
a = [1 -2 1];
h_l = filter(b,a,[1 zeros(1,12)]);
ecg_l = conv (ecg ,h_l);
但是java中没有filter
和conv
这样的功能(或者我漏掉了什么)。
我也在 Whosebug 上寻找答案。但是我没有找到关于传递函数的任何信息。
所以有人可以帮助我吗?我只想继续我的项目。
给定一个time-domain递归方程(比如你从维基百科引用的那个),z-domain中的相应传递函数可以通过使用以下属性相对容易地获得:
其中X(z)
和Y(z)
分别是time-domain输入序列x
和输出序列y
的z-transforms。
反过来,给定一个传递函数,可以表示为 z 中多项式的比率,例如:
传递函数的递归方程可以写成:
当然有许多不同的方法来实现这样的递归方程,但是遵循 Direct Form II 的简单过滤器实现将遵循:
// Implementation of an Infinite Impulse Response (IIR) filter
// with recurrence equation:
// y[n] = -\sum_{i=1}^M a_i y[n-i] + \sum_{i=0}^N b_i x[n-i]
public class IIRFilter {
public IIRFilter(float a_[], float b_[]) {
// initialize memory elements
int N = Math.max(a_.length, b_.length);
memory = new float[N-1];
for (int i = 0; i < memory.length; i++) {
memory[i] = 0.0f;
}
// copy filter coefficients
a = new float[N];
int i = 0;
for (; i < a_.length; i++) {
a[i] = a_[i];
}
for (; i < N; i++) {
a[i] = 0.0f;
}
b = new float[N];
i = 0;
for (; i < b_.length; i++) {
b[i] = b_[i];
}
for (; i < N; i++) {
b[i] = 0.0f;
}
}
// Filter samples from input buffer, and store result in output buffer.
// Implementation based on Direct Form II.
// Works similar to matlab's "output = filter(b,a,input)" command
public void process(float input[], float output[]) {
for (int i = 0; i < input.length; i++) {
float in = input[i];
float out = 0.0f;
for (int j = memory.length-1; j >= 0; j--) {
in -= a[j+1] * memory[j];
out += b[j+1] * memory[j];
}
out += b[0] * in;
output[i] = out;
// shift memory
for (int j = memory.length-1; j > 0; j--) {
memory[j] = memory[j - 1];
}
memory[0] = in;
}
}
private float[] a;
private float[] b;
private float[] memory;
}
您可以使用它来实现您的特定传递函数,如下所示:
float g = 1.0f/32.0f; // overall filter gain
float[] a = {1, -2, 1};
float[] b = {g, 0, 0, 0, 0, 0, -2*g, 0, 0, 0, 0, 0, g};
IIRFilter filter = new IIRFilter(a, b);
filter.process(input, output);
请注意,您也可以将分子和分母因式分解为 2nd 阶多项式,并获得 2nd 阶滤波器的级联(称为 biquad filters)。
我正在尝试处理 android 中的 ECG 信号处理。我想实现简单的数字滤波器(低通、高通)
我有一个传递函数:
这是我发现的:
wikipedia - lowpass filter - 这里看起来很简单。
for i from 1 to n
y[i] := y[i-1] + α * (x[i] - y[i-1])
但是没有关于我想使用的传递函数的任何信息。
我还找到了下面的matlab代码
%% Low Pass Filter H(z) = (1 - 2z^(-6) + z^(-12)) / (1 - 2z^(-1) + z^(-2))
b = [1 0 0 0 0 0 -2 0 0 0 0 0 1];
a = [1 -2 1];
h_l = filter(b,a,[1 zeros(1,12)]);
ecg_l = conv (ecg ,h_l);
但是java中没有filter
和conv
这样的功能(或者我漏掉了什么)。
我也在 Whosebug 上寻找答案。但是我没有找到关于传递函数的任何信息。
所以有人可以帮助我吗?我只想继续我的项目。
给定一个time-domain递归方程(比如你从维基百科引用的那个),z-domain中的相应传递函数可以通过使用以下属性相对容易地获得:
其中X(z)
和Y(z)
分别是time-domain输入序列x
和输出序列y
的z-transforms。
反过来,给定一个传递函数,可以表示为 z 中多项式的比率,例如:
传递函数的递归方程可以写成:
当然有许多不同的方法来实现这样的递归方程,但是遵循 Direct Form II 的简单过滤器实现将遵循:
// Implementation of an Infinite Impulse Response (IIR) filter
// with recurrence equation:
// y[n] = -\sum_{i=1}^M a_i y[n-i] + \sum_{i=0}^N b_i x[n-i]
public class IIRFilter {
public IIRFilter(float a_[], float b_[]) {
// initialize memory elements
int N = Math.max(a_.length, b_.length);
memory = new float[N-1];
for (int i = 0; i < memory.length; i++) {
memory[i] = 0.0f;
}
// copy filter coefficients
a = new float[N];
int i = 0;
for (; i < a_.length; i++) {
a[i] = a_[i];
}
for (; i < N; i++) {
a[i] = 0.0f;
}
b = new float[N];
i = 0;
for (; i < b_.length; i++) {
b[i] = b_[i];
}
for (; i < N; i++) {
b[i] = 0.0f;
}
}
// Filter samples from input buffer, and store result in output buffer.
// Implementation based on Direct Form II.
// Works similar to matlab's "output = filter(b,a,input)" command
public void process(float input[], float output[]) {
for (int i = 0; i < input.length; i++) {
float in = input[i];
float out = 0.0f;
for (int j = memory.length-1; j >= 0; j--) {
in -= a[j+1] * memory[j];
out += b[j+1] * memory[j];
}
out += b[0] * in;
output[i] = out;
// shift memory
for (int j = memory.length-1; j > 0; j--) {
memory[j] = memory[j - 1];
}
memory[0] = in;
}
}
private float[] a;
private float[] b;
private float[] memory;
}
您可以使用它来实现您的特定传递函数,如下所示:
float g = 1.0f/32.0f; // overall filter gain
float[] a = {1, -2, 1};
float[] b = {g, 0, 0, 0, 0, 0, -2*g, 0, 0, 0, 0, 0, g};
IIRFilter filter = new IIRFilter(a, b);
filter.process(input, output);
请注意,您也可以将分子和分母因式分解为 2nd 阶多项式,并获得 2nd 阶滤波器的级联(称为 biquad filters)。