最近有一个需求,在C#中实现FIR滤波,网上查了些资料感觉FIR滤波使用的还算比较多,相关的原理也比较简单。参考下面在Python环境中实现FIR的博客,在C#的环境中实现了一遍。
https://blog.csdn.net/moge19/article/details/94495442(Python实现FIR带通滤波器)
下文中的工程下载链接:https://download.csdn.net/download/zhoudapeng01/12036955
一、FIR滤波器的设计,这里使用Matlab进行设计:
filterDesigner命令启动工具箱
设计FIR带通滤波,这里设计32阶,125-300赫兹,Hamming窗
输出设计的滤波器:这里面有3种不同的输出模式,你可以都输出看看,本质上都是同一个滤波器,只不过表现形式不同而已。
matlab中的滤波效果验证(使用的是第一个选项生成的脚本,这里保存为FilteDesign1):
第一列为时域数据,第二列为频域数据。
第一行为输入数据,第二行为FIR滤波器的结果,第三行为理想的滤波结果,图中可以看出滤波后的频谱和理想频谱还算接近,具体的效果需要根据实际情况调节阶数等滤波器的参数。
clc;clear;clf;close all
t = 0:0.001:0.05;
%原始数据
y = 0.7*sin(2*pi*30*t) + 1.8*sin(2*pi*160*t) + 5.1*sin(2*pi*330*t) ;
fft_y = abs(fft(y));
subplot(3,2,1);
plot(y)
subplot(3,2,2);
plot(fft_y)
%FIR滤波结果125-300
H = filter(FilteDesign1,y);
% H = filter(FilteDesign1,H');
fft_H = abs(fft(H));
subplot(3,2,3);
plot(H)
subplot(3,2,4);
plot(fft_H)
%理想结果
yH = 1.8*sin(2*pi*160*t);
fft_yH = abs(fft(yH));
subplot(3,2,5);
plot(yH)
subplot(3,2,6);
plot(fft_yH)
二、FIR带通滤波的C#实现
个人理解滤波器的原理就是一句话:频域的乘积就是时域的卷积。实现滤波器的本质就是实现卷积运算,我们可以在matlab中获取上面设计滤波器的系数,在保存滤波器的时候选择第三个,在matlab函数中就可以获取到滤波器的系数h(i)。
C#的实现代码,filterParameters为对应的滤波器参数,其中CalcFIR为计算的核心部分,其输入参数为输入信号,返回值为滤波后的信号。
using System;
using System.Collections.Generic;
using System.Text;
namespace AlgorithmCSharp.Filter
{
class FilterFIR
{
public List<double> filterParameters { get; set; }
public FilterFIR(List<double> parameters)
{
filterParameters = parameters;
}
public double[] CalcFIR(double[] dataSerial)
{
int length = dataSerial.Length;
int order = filterParameters.Count;
double[] FIRResult = new double[length];
for(int i =0; i<length; i++)
{
double sum = 0;
if(i<order)
{
for(int j =0; j<i;j++)
{
sum += filterParameters[j] * dataSerial[i - j];
}
}
else
{
for(int j=0; j<order; j++)
{
sum += filterParameters[j] * dataSerial[i - j];
}
}
FIRResult[i] = sum;
}
return FIRResult;
}
}
}
对应的资源下载地址: https://download.csdn.net/download/zhoudapeng01/12036955