设计因果 FIR 滤波器来近似希尔伯特变换

信息处理 过滤器设计 希尔伯特变换
2022-02-17 18:30:13

我正在尝试设计一个近似希尔伯特变换的 FIR 滤波器,以获得90相移和单位增益。但是,我无法调整过滤器以使其成为因果关系。我已经阅读了这个答案,这非常有帮助。这是我到目前为止所得到的。

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal.windows import hamming

N = 50
H = hamming(2 * N + 1)


def coeff(n):
    if n == 0:
        return 0
    return H[int(n + N - 1)] * (2 / np.pi) * (np.sin(np.pi * n / 2) ** 2 / n)


def freq(w):
    return np.sum(
        [coeff(n) * np.exp(-1 * 1j * w * n) for n in range(-N, N + 1)]
    )


if __name__ == "__main__":
    freq_vals = np.linspace(0, np.pi, 1000)
    freq_resp = [np.abs(freq(w)) for w in freq_vals]
    ang_resp = [np.angle(freq(w)) for w in freq_vals]
    # plot frequency response
    plt.plot(freq_vals / np.pi, freq_resp)
    # plot phase shift
    plt.plot(freq_vals / np.pi, ang_resp)
    plt.show()

coeff使用等式计算理想的希尔伯特变换系数

h[n]={2πsin2(πn/2)nn0,0n=0,

我取自离散时间信号处理 (3e) p.959。我已经限制n[50,50]. 此外,它应用汉明窗来减少吉布斯现象(参见上面的链接答案)。

freq然后使用等式计算给定频率值的频率响应

H(ω)=n=h[n]einω.

现在,当我绘制这个(plt.plot线)时,我得到了我期望的幅度和相位响应:

mag (x 范围是 0 到ω,我已将其标准化为 1): 在此处输入图像描述

阶段: 在此处输入图像描述

但是,我计算了脉冲响应值h[50],h[49],,h[50]. 所以,这个过滤器不是因果的。我相信这个过滤器应该是时间不变的,所以我试图简单地改变它,以便n现在范围从 0 到2N+1. 这是调整后的freq功能:

def freq(w):
    return np.sum(
        [coeff(n - N) * np.exp(-1 * 1j * w * n) for n in range(0, 2 * N + 1)]
    )

这会产生相同的频率幅度响应,但具有以下“不正确”的相位响应: 在此处输入图像描述

我希望我误解了这个过程的一些基本内容,但我不确定是什么。我怎样才能使这个滤波器与所需的相位响应有因果关系?为什么我试图使滤波器因果保持正确的幅度响应而不是相位响应?

1个回答

基本上,根据定义,希尔伯特变换器是非因果的,总是任何零相位滤波器都是非因果的。我们可以及时移动脉冲,但相位随后变为线性而不是平坦(频率的函数)。

要实现,输入信号必须延迟滤波器长度减一的一半(N在这种情况下)。或者可以将输入信号与希尔伯特脉冲进行卷积(如您所做的那样,加窗以最小化吉布斯)。从来没有做过后者,所以检查自己。

但!有一种配置使用一对 4 阶全通滤波器,它们的相位相差非常接近 90 度。不幸的是,每个输出的相位都与原始相位不同,但根据您的需要,它可以被黑客入侵......

参考:https ://www.dspguide.com/ch19/4.htm ,在 matlab 上设计希尔伯特滤波器(纯 90 相位和幅度 0db)