实时零相位滤波的神话(1)

做控制的人大概都梦想做到输出和输入信号保持完全同步,相移为0。如果能做到,那该多酷。

MATLAB有个神奇的函数filtfilt,可以对数据做离线的滤波,实现零相移。原理就是先做一个方向的滤波,比如先forward 滤波,然后把滤波后的序列逆序,再用同一个滤波器做backward滤波,滤波得到的序列最后再逆序,得到最终结果。尝试了一下,滤波效果那真是赏心悦目。可惜,不能实现在线信号的实时零相移滤波。怎么做呢?焦虑之际,在百度上搜到这个文章:http://blog.csdn.net/shenziheng1/article/details/53415642,作者的手段让我万分佩服:既然相移导致的group delay不为0,那咱就设计个group delay与其完全相反的全通滤波器,二者级联,groupdelay两两相消,不就搞定了吗?多么完美!!

感谢这位博主,在相关文章里把代码给的相当完整,某些略去的地方其实比较容易补全。按照这个思路做下去,确实得到了相移接近0 的结果,图片如下:

但是当我兴冲冲地把low pass 和all pass级联进行滤波,得到了让人郁闷的玩意:滤波结果是震荡的,数据越来越大。。。。痛苦地找了好久,某篇英文文章说,级联allpass滤波器,只能增大相移,尤其是在将iir整成线性相位滤波器时的典型应用时,group delay在通带内虽然可以保持恒定,但只能让group delay变大,即输出结果比输入delay更多个samples。这个震荡,应该是all pass的零极点与单位圆的关系导致系统不稳定造成的。

iir+all pass常用来进行相位均衡,这个均衡并不是要做到零相位,而是使得通带内的信号保持固定的group delay。下面是从某个大学课件上搞来的iir+all pass的代码,讲解了相位均衡的常规应用:

t = 0:0.001:1;


w = pi*t; % normalized frequencies
alpha = 0.5; % LPF parameter
blp = (1-alpha)/2*[1 1]; % numerator coefficients
alp = [1 -alpha]; % denominator coefficients
hlp = freqz(blp,alp,w); % compute DTFT
glp = grpdelay(blp,alp,w); % compute group delay


N = 4; % all-pass filter order
F = w(1:501)/pi; % normalized frequencies
edges = [0 1/2]; % band-edge frequencies
Gd = max(glp)-glp(1:501); % desired group-delays of APF (>0)
[bap,aap] = iirgrpdelay(N,F,edges,Gd); % make all-pass filter
hap = freqz(bap,aap,w); % compute DTFT
gap = grpdelay(bap,aap,w); % compute group-delay

b = conv(blp,bap); % product of numerators
a = conv(alp,aap); % product of denominators
h = freqz(b,a,w); % compute DTFT
g = grpdelay(b,a,w); % compute group delay
subplot(3,1,1)
plot(w,abs(h));
ylabel('magnitude response');
subplot(3,1,2);
plot(w,unwrap(angle(h)));
ylabel('phase response (rad)');
subplot(3,1,3);
plot(w,g);
xlabel('normalized freq (rad/sample)');
ylabel('group delay (samples)');

已经确定了,all pass 级联不能让group delay 变成0,反而是更大。于是,我的第一次充满勇气的寻找零相位实时滤波器行动宣告破产。

  • 11
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MATLAB中的相位滤波可以使用filtfilt函数来实现。该函数的原理是先对信号进行前向滤波,然后将滤波后的序列逆序,再次使用相同的滤波器进行反向滤波,最后再次逆序得到最终结果。这样可以实现相移的滤波效果。然而,filtfilt函数只适用于离线滤波,无法在实时信号中实现相移滤波。 如果想在实时信号中实现相移滤波,可以采用其他方法。例如,可以设计一个全通滤波器,其group delay与待滤波信号的group delay完全相反,然后将两个滤波器级联。这样,两者的group delay将相互抵消,从而实现了相移滤波效果。这种方法可以通过参考一篇CSDN博客文章中的内容进行实现,链接为:http://blog.csdn.net/shenziheng1/article/details/53415642。 另外,如果使用MATLAB进行相位滤波,可以使用filtfilt函数,该函数可以在一次运行中实现前向和反向滤波,并得到相位滤波的结果。代码示例可以参考引用中的MATLAB代码。 总结来说,MATLAB中的相位滤波可以使用filtfilt函数实现,也可以通过设计全通滤波器进行级联来实现。具体选择哪种方法取决于应用的需求和实际情况。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [实时相位滤波神话(1)](https://blog.csdn.net/csdn_kike/article/details/69056066)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MATLAB函数:filtfilt——相位数字滤波](https://blog.csdn.net/WandZ123/article/details/125915042)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [实时相位滤波神话(2)](https://blog.csdn.net/csdn_kike/article/details/69061673)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值