在matlab中我们可以使用filtfilt函数来过滤掉实现前向和后向过滤技术的数据,从而产生零相位。但是实时实现这个过滤器很困难,因为它涉及反向过滤。
我想实现实时零相位的一阶高通或低通滤波器。我怎样才能实现这一目标?
我已经在网上搜索了好几天但却无法从中获取任何线索!
提前致谢!
答案 0 :(得分:23)
不可能实时执行零相位滤波器,因为零相位滤波器需要在零附近对称的滤波器系数。这意味着过滤器是非因果的,或者当前输出取决于未来的输入。这当然在实时案例中是不可能的,并且可以在后处理期间伪造filtfilt
。
您可能正在寻找的是linear phase过滤器。不要让这个名字混淆你;这并不意味着滤波器会产生任何相位失真。它只表示将时移应用于输出。相对于频率的线性相移导致相对于时间的恒定偏移。所以基本上你的输出会从输入延迟一些恒定数量的样本(group delay)。
因此,零相位和线性相位滤波器之间的唯一区别在于线性相位滤波器输出是零相位输出的延迟版本。如果您需要使输出与输入保持一致,则可以通过跟踪群延迟来解决此延迟。
对评论的回应:
如果FIR滤波器的系数关于中心对称,则保证它们是线性相位。 MATLAB可以使用fir1或firpm等功能轻松创建这些类型的过滤器。这些函数文档中的示例应该向您展示如何使用它们。
线性相位FIR滤波器的群延迟为(L-1)/2
,其中L
是滤波器的长度。由于这个和其他一些事情,我通常会选择一个奇数的滤波器长度,因此延迟与样本对齐,而不是在样本之间。这基本上意味着输出信号将从(L-1)/2
样本的输入延迟。
实现过滤器的实际过滤过程基本上是discrete convolution。这涉及反转滤波器系数,将它们乘以最近的L
输入样本,并添加这些结果以生成单个输出样本。然后引入新的输入样本并再次完成整个过程以产生另一个样本(在滑动窗口上进行多次和求和)。您应该能够在网上找到一些卷积的示例代码。
这是执行FIR滤波的直接方法,但对于更长的滤波器,使用FFT执行fast convolution可能更有效。这将是更难以正确的,所以除非你在谈论高采样率和长滤波器,否则我会采用直接方法。
答案 1 :(得分:1)
“非因果”零相位滤波器加上足够量的相加延迟可以通过因果线性相位FIR滤波器来近似。这假设添加一些延迟符合您的系统要求。
在你的情况下,你可以采取你的前向+后向非对称(或非线性相位)滤波过程的脉冲响应,脉冲响应的窗口使响应有限的长度,延迟有限长度内核使它不不需要“未来”样本,并将其用作FIR滤波器内核。您必须检查结果,看看您选择的窗口是否适合长度和形状。由于该延迟所需的有限长度窗口,可能需要在选择延迟与滤波器质量方面进行权衡。