发新帖本帖赏金 5.00元(功能说明)我要提问
1234
返回列表
打印

请问如何进行FFT滤波

[复制链接]
楼主: a3724395
手机看帖
扫描二维码
随时随地手机跟帖
61
a3724395|  楼主 | 2017-10-11 21:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
nethopper 发表于 2017-9-30 12:21
FFT滤波需要找准FFT结果中的各点所对应的中心频率,这个貌似简单,但却容易出错。下图显示了FFT结果中的各 ...

经测量,输入10HZ波形,fs=200HZ,N=200点,FFT后计划滤掉10HZ的输入,做法是将第10点或第10点及246点置0,图形如下(黄输入绿输出),图1是FFT-IFFT但没滤波的输入和输出波形(说明FFT,IFFT及采样-输出等程序没问题),图二是加入滤波程序的输入和输出波形,从波形看应该是没有达到滤波效果?
滤波程序:
FFT(s,1);
s[10].real=0.0;
s[10].imag=0.0;
s[246].real=0.0;
s[246].imag=0.0;
FFT(s,-1);

没滤波.png (120.1 KB )

FFT后没滤波

FFT后没滤波

滤波.png (114 KB )

FFT后滤波

FFT后滤波

使用特权

评论回复
62
a3724395|  楼主 | 2017-10-11 21:19 | 只看该作者
黄输入蓝输出

使用特权

评论回复
63
a3724395|  楼主 | 2017-10-11 21:34 | 只看该作者
a3724395 发表于 2017-10-11 21:15
经测量,输入10HZ波形,fs=200HZ,N=200点,FFT后计划滤掉10HZ的输入,做法是将第10点或第10点及246点置0 ...

补充说明,s[256],对256点FFT,只不过后56点都置0了

使用特权

评论回复
64
nethopper| | 2017-10-15 17:25 | 只看该作者
a3724395 发表于 2017-10-11 21:34
补充说明,s[256],对256点FFT,只不过后56点都置0了

你没算对,采样率200Hz, 256点FFT的频率分辨率是200Hz/256=0.78125Hz, 不是200Hz/200=1Hz, 尽管你用的是200个数据点+后面补56个零。

由于10/0.78125=12.8,所以FFT滤波应将第12个点、第13个点、第256-12=244个点、第256-13=243个点置0。

下面是按你这个数据做的FFT滤波,黄色是滤波前的信号(B通道),蓝绿色(A通道)是FFT滤波后的信号,带阻滤波的阻带选在9Hz~11Hz。由图可见,除了前端和尾端有点边界效应外(尾部补零应该减缓了边界效应),中部滤波效果OK。



下面是原始数据文件。
Book1.rar (1.47 KB)

使用特权

评论回复

打赏榜单

a3724395 打赏了 5.00 元 2017-12-21
理由:高手,值得学习!

65
a3724395|  楼主 | 2017-10-17 11:29 | 只看该作者
一周一天班 发表于 2017-9-9 09:28
FFT是一个周期(一段时间)内的分析,不能用于实时的滤波。两码事情。

Fir实时滤波是什么思路,实时滤波应该是采集一个数据输出一个数据,可我看教材也是采集一段数据再进行滤波,抛开域,感觉做法和fft滤波差不多啊

使用特权

评论回复
66
Wattle_He| | 2017-10-17 13:24 | 只看该作者
wu_npu 发表于 2017-9-7 22:49
然后回到时域你会发现,相位全乱了

这……也能乱?
FFT出来的结果是复数,包含每个频点的相位信息
除非是做的功率谱,那才是不含相位信息的

使用特权

评论回复
67
Wattle_He| | 2017-10-17 13:33 | 只看该作者
a3724395 发表于 2017-10-17 11:29
Fir实时滤波是什么思路,实时滤波应该是采集一个数据输出一个数据,可我看教材也是采集一段数据再进行滤 ...

你看的教材应该是针对于顺序执行语言来写的
FPGA中的FIR滤波器各类书本给的例子都是实时的
思路上就是相当于开了一个能存N个数的“FIFO”当“缓存”
进去一个数,把最老的数据踢出去,然后再和之前按顺序进来的N-1个数一起,计算FIR
得到一个结果,丢出来

为啥可以只丢一个结果出来,而不是像顺序执行语言里面进去一串丢出来一串?
你把循环拆开就明白了

使用特权

评论回复
68
a3724395|  楼主 | 2017-10-17 18:56 | 只看该作者
Wattle_He 发表于 2017-10-17 13:33
你看的教材应该是针对于顺序执行语言来写的
FPGA中的FIR滤波器各类书本给的例子都是实时的
思路上就是相当 ...

按照这位老师的理解,中心语句难道是:
for(i=0;i<31;i++)              //假设系数 h[32], 输入缓冲数组 x[32],for语句先对x[32]移位。
{
    x=x[i+1];                 //移位
}
x[31]=read0832(1);        //每次采集的数据放在 x[31]中
sum=0;
for(j=0;j<32;j++)          //每次对 x[31]进行滤波
{
     sum+=h[j]*x[31-j];   
}
out=sum;                     //x[31]的滤波结果作为输出。
不知我理解的是否正确,试验结果好像不怎么正确。

使用特权

评论回复
69
a3724395|  楼主 | 2017-10-17 19:05 | 只看该作者
nethopper 发表于 2017-10-15 17:25
你没算对,采样率200Hz, 256点FFT的频率分辨率是200Hz/256=0.78125Hz, 不是200Hz/200=1Hz, 尽管你用的是2 ...

确实是计算错了,按照您的改了一下好很多,仍以滤除10HZ的方波为例,滤波结果如下图,
唯一的担忧是方波两端衰减的并不大,不知是不是真正达到了滤波的效果?

22.jpg (254.9 KB )

方波两端幅值仍很大

方波两端幅值仍很大

使用特权

评论回复
70
nethopper| | 2017-10-20 21:48 | 只看该作者
a3724395 发表于 2017-10-17 19:05
确实是计算错了,按照您的改了一下好很多,仍以滤除10HZ的方波为例,滤波结果如下图,
唯一的担忧是方波 ...

这次应该是对的,方波把基波滤掉后应该就是这个样子的,阶梯可能是由于垂直分辨率不够引起。

使用特权

评论回复
71
a3724395|  楼主 | 2017-10-21 08:55 | 只看该作者
nethopper 发表于 2017-10-20 21:48
这次应该是对的,方波把基波滤掉后应该就是这个样子的,阶梯可能是由于垂直分辨率不够引起。 ...

谢谢指点!

另外FIR滤波器程序(C语言)的实现是通过两个for循环完成卷积运算,跟FFT一样也要采集一串数据进行,没发现楼上说的FIR具有实时性,难道FIR能每采集一个数据进行一次滤波并输出吗?通过定义一个数组x[],每次x[]往前移一位(第一位旧的数据溢出),最后一位存储新的采集数据,只对最后一位FIR滤波并输出,可以这样做吗?通过实验采集一串数据的没问题,这种一进一出的好像不对

使用特权

评论回复
72
nethopper| | 2017-10-24 19:55 | 只看该作者
a3724395 发表于 2017-10-21 08:55
谢谢指点!

另外FIR滤波器程序(C语言)的实现是通过两个for循环完成卷积运算,跟FFT一样也要采集一串数 ...

FIR滤波的所谓的“实时”是说输入一个点,就输出一个点,但缓冲区需要始终保存一定长度的最近的输入数据来与数字滤波器的单位冲激响应做卷积,最开始没有数据的时候就填零。线性相位的FIR的输出比输入会延迟[FIR阶数]/2个点。

FFT滤波是输入一段数据,就输出一段数据,如果想点办法,同样可以实现表面上的一点一点地输出,关键是FFT滤波是循环卷积,直接这样做会出现每个FFT段反变换回时域的数据在FFT段的边界处很可能是不连续的,换种说法也可叫做存在时域混叠。可通过时域补零来将循环卷积变为线性卷积,换种说法也可叫做增加频域采样率,来避免时域混叠。

FIR是一点一点地输出,为每点输出所做的卷积无法通过优化来加速;而FFT是一段一段地输出,可通过削减大数据计算中的重复计算来实现加速。就好比团购比单购省钱一样。因此,也有FIR通过采用FFT来加速的,主要就是想法用FFT的循环卷积实现FIR线性卷积的效果。

使用特权

评论回复
73
a3724395|  楼主 | 2017-10-25 10:34 | 只看该作者
nethopper 发表于 2017-10-24 19:55
FIR滤波的所谓的“实时”是说输入一个点,就输出一个点,但缓冲区需要始终保存一定长度的最近的输入数据 ...

测试了一下,FIR每输入一个点滤波并输出,发现滤波器如果是32阶的话,通过卷积运算滤波用时8ms,如果是165阶的话用时40ms,用时太长,如果采样频率是2000hz(每0.5毫秒采样一次)的话,那么实际采样时间可能是8ms以上或40ms以上(针对32阶和165阶),那采集的就不正确了,是这样吧!

如果对输入的每一点,卷积运算改为频域的FFT相乘,或许可以节省点时间?那么问题是FIR的理论要求输入一点只能输出一点,那么FFT乘积再IFFT到时域得到的应该是一串数据吧,那怎么才能保证输出是一点呢?

使用特权

评论回复
74
nethopper| | 2017-10-26 22:18 | 只看该作者
a3724395 发表于 2017-10-25 10:34
测试了一下,FIR每输入一个点滤波并输出,发现滤波器如果是32阶的话,通过卷积运算滤波用时8ms,如果是16 ...

芯片的运算速度太慢就没办法了,FFT虽然可加速,但在FFT点数比较小的时候,overhead较大,可能并不划算。FFT点数大的话,加速就多,但需要的缓冲就大,信号的延迟就大。

使用特权

评论回复
75
a3724395|  楼主 | 2017-10-27 09:34 | 只看该作者
nethopper 发表于 2017-10-26 22:18
芯片的运算速度太慢就没办法了,FFT虽然可加速,但在FFT点数比较小的时候,overhead较大,可能并不划算。 ...

点数少时,用FFT比直接用卷积还要浪费时间,教材介绍FIR时有一种方法叫快速卷积算法,序列补充一定长度后用了FFT,这种方法只适用于采集一串数据后滤波,不适用FIR的实时滤波吗?

使用特权

评论回复
76
ddc21ic| | 2018-11-30 20:41 | 只看该作者
标记一下,FFT滤波

使用特权

评论回复
发新帖 本帖赏金 5.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则