天天看点

基于java的滤波器设计(IIR)

IIR滤波器的表达式为:

y(n)+∑i=1Na(i)y(n−i)=∑k=0Mb(k)x(n−k)

所以首要任务是确定系数a,b,在这里我选择直接使用MATLAB生成系数a,b

在MATLAB命令行中输入fdatool,打开fdatool

基于java的滤波器设计(IIR)

在fdatool里面可以设置参数,我在这里设置采样率是250hz,fs是55hz,fp60hz

基于java的滤波器设计(IIR)

选择好之后生成滤波器,选择File->Export

基于java的滤波器设计(IIR)

在工作区就会得到两个向量SOS和G,使用命令语句转换成a,b

基于java的滤波器设计(IIR)

将a和b导出生成.txt文件

基于java的滤波器设计(IIR)

a和b可以直接复制到.java文件的数组内,以下是IIR滤波器算法

package highpass;

public class highpass {                         
    private static double[]             a={在这里复制a};                           
    private static double[]             b={在这里复制b};      

    private static double[]             in;                         
    private static double[]             out; 
    private static double[]             outData; 



    public double[] IIRFilter (double[] signal) {
          in=new double[b.length];
          out=new double[a.length-1];
          outData=new double[signal.length];
          for (int i = 0; i < signal.length; i++) {

                System.arraycopy(in, 0, in, 1, in.length - 1);  //in[1]=in[0],in[2]=in[1]...
                in[0] = signal[i];

                //calculate y based on a and b coefficients
                //and in and out.
                double y = 0;
                for(int j = 0 ; j < b.length ; j++){
                    y += b[j] * in[j];

                }

                for(int j = 0;j < a.length-1;j++){
                    y -= a[j+1] * out[j];
                }

                //shift the out array
                System.arraycopy(out, 0, out, 1, out.length - 1);
                out[0] = y;

                outData[i] = y;


            }
          return outData;
    }

}
           

接下来我们测试一下算法是否工作正常

首先在MATLAB里生成一个45hz和65hz相加的数组x,并将x导出成txt文件

Fs=250;
t=(1:2048)/Fs;
x=sin(2*pi*45*t)+cos(2*pi*65*t);
fid=fopen('x.txt','wt');
fprintf(fid,'%g\n',x);
fclose(fid);           

然后在eclipse里写一个main函数,把x.txt复制到输入数组,在设定的路径下就可以得到滤波后的结果:

public static void main(String[] args) throws IOException {
        File file=null;
        FileWriter fw=null;
        file=new File("F:\\result.txt");
        fw= new FileWriter(file);
        highpass a=new highpass();
        double[] in= {复制x.txt};
        double[] out=a.IIRFilter(in);
        for(int i=0;i<out.length;i++) {
            fw.write(String.valueOf(out[i]));
            fw.write("\r\n");
        }
        fw.flush();
        }           

将result.txt文件里的数据进行频谱分析,可惜最终发现滤波后发生了震荡,由于数字不是我的研究方向,代码是没有问题的,但是我也分析不出来为什么震荡了,有可能是保留的有效数字的问题,所以果断转向FIR,见下一篇。

基于java的滤波器设计(IIR)