从原始信号中减去低通滤波信号并将结果用作“高通”是否正确?

信息处理 Python 带通 高通滤波器
2022-01-04 11:38:14

我很难找到使用 python/scipy/numpy 实现带通或高通滤波器的文档。

不过,我可以轻松地创建和应用低通滤波器,所以我问:

对信号进行低通滤波,然后从原始信号中减去结果,以获得高频,在概念上是否正确?

此外,如果有人在 Python 中有一个简单的带通滤波器示例(最好使用 numpy 和 scipy 库),我将非常感激。

我寻找的是这样的:

filtered_signal = band_pass(original_signal, rate, low=20, high=500)

谢谢你的帮助!

编辑:使用 scipy,我将其用作低通,效果很好:

import numpy, scipy.signal

def firfilt(interval, freq, sampling_rate):
    nfreq = freq/(0.5*sampling_rate)
    taps =  sampling_rate + 1
    a = 1
    b = scipy.signal.firwin(taps, cutoff=nfreq)
    firstpass = scipy.signal.lfilter(b, a, interval)
    ## second pass to compensate phase delay
    secondpass = scipy.signal.lfilter(b, a, firstpass[::-1])[::-1]
    return secondpass
3个回答

理论上你可以做到这一点,但实际上很难做到,因为时间和相位对齐必须非常好才能工作。如果对齐良好,您将获得您正在寻找的破坏性干扰如果他们不是,你会得到一些建设性的干扰。更糟糕的是,它们是破坏性干扰还是建设性干扰将取决于频率 - 即您可以同时获得建设性和破坏性干扰。但是,如果您只滤除相当低的频率,它可以工作,因为它们的时序要求是最宽松的,因为它们变化如此缓慢。

短篇小说 - 可以做到,但难度很大,通常只做一个高通滤波器是有意义的。

创建带通滤波器的一种相对简单的方法是创建一个低通滤波器,然后将其与该频率的正弦曲线相乘,将其调制到您想要的中心频率。

您可以直接使用 scipy.signal 函数设计不同的过滤器类型。使用 scipy.signal 包创建有限脉冲响应滤波器有三个主要功能。

  1. 信号.remez
  2. 信号.firwin
  3. 信号.firwin2

remez函数作为参数,采用抽头数(阶数+1)、“频带”和“所需”增益。“频带”以赫兹为单位。这个函数有点奇怪,“Hz”参数以Hz为单位定义采样率。一个例子是:

from scipy import signal
b = signal.remez(64, [0, 80, 100, 200, 220, 500], [0, 1, 0], Hz=1000)
plot(20*log10(abs(fft.fft(b, 4096).)))

频率响应

注意:我作弊了一点,并使用了更高阶的 FFT 来使绘图看起来更好一些(插入点仅用于可视化)。

低通和高通示例:

bl = signal.remez(64, [0, 248, 252, 500], [1, 0], Hz=1000) #lowpass
bh = signal.remez(64, [0, 248, 252, 500], [0, 1], Hz=1000) #highpass

firwin函数再次将抽头数和截止值作为参数截止可以是多个值作为列表来定义带通和阻带滤波器。截止的默认单位是归一化频率,其中奈奎斯特截止为 1,采样率为 2。这可以通过设置 /nyq/ 来修改。使用上面的示例, firwin 将被称为:

b = signal.firwin(64, [100, 200], pass_zero=False, nyq=500)

firwin2更接近 remez函数。但是,您不会在频段上传递收益,而是在截止时传递收益。

b = signal.firwin2(64, [0, 100, 200, 500], [0, 1, 1, 0], nyq=500)

此处提供更多示例

您表示您无法弄清楚如何设计合适的高通滤波器。一种方法是首先设计一个低通滤波器原型,然后应用将滤波器的响应扭曲到另一种类型的滤波器(例如高通或带通滤波器)的变换。这是通过将表达式替换为z1到原型低通滤波器的传递函数中。以下是有关该主题的信息的一些链接:

具体来说,对于低通到高通的转换,您可以应用以下替换:

z1=α+z11+αz1,
α=cos(12(ωcωc))cos(12(ωc+ωc))

在哪里ωc是低通滤波器原型的截止频率和ωc是转换后的高通滤波器中产生的截止频率。第一个链接中显示的 MATLAB 文档中给出了一些示例。SciPy 中可能有类似的功能。话虽如此,该库中的许多滤波器设计函数都非常接近 MATLAB 的示例,并且它们能够轻松设计所有主要类型(低通、高通等)的滤波器。