【问题标题】:Python: High Pass FIR Filter by WindowingPython:开窗的高通 FIR 滤波器
【发布时间】:2014-04-28 23:35:27
【问题描述】:

我想在 Python 中通过窗口化创建一个基本的高通 FIR 滤波器。

我的代码在下面并且是故意惯用的 - 我知道您可以(很可能)用 Python 中的一行代码完成此操作,但我正在学习。我使用了带有矩形窗口的基本 a sinc 函数:我的输出适用于加法 (f1+f2) 但不是乘法 (f1*f2) 的信号,其中 f1=25kHz 和 f2=1MHz。

我的问题是:我误解了一些基本的东西还是我的代码有误? 总之,我想只提取高通信号(f2=1MHz)并过滤掉其他所有信号。我还包括了为 (f1+f2) 和 (f1*f2) 生成的屏幕截图:

import numpy as np
import matplotlib.pyplot as plt

# create an array of 1024 points sampled at 40MHz
# [each sample is 25ns apart]
Fs = 40e6
T  = 1/Fs
t  = np.arange(0,(1024*T),T)

# create an ip signal sampled at Fs, using two frequencies 
F_low  = 25e3 #  25kHz
F_high = 1e6  #  1MHz
ip = np.sin(2*np.pi*F_low*t) + np.sin(2*np.pi*F_high*t)
#ip = np.sin(2*np.pi*F_low*t) * np.sin(2*np.pi*F_high*t)
op = [0]*len(ip)


# Define -
# Fsample = 40MHz
# Fcutoff = 900kHz,
# this gives the normalised transition freq, Ft
Fc = 0.9e6
Ft = Fc/Fs
Length       = 101
M            = Length - 1
Weight       = []
for n in range(0, Length):
    if( n != (M/2) ):
        Weight.append( -np.sin(2*np.pi*Ft*(n-(M/2))) / (np.pi*(n-(M/2))) )
    else:
        Weight.append( 1-2*Ft )




for n in range(len(Weight), len(ip)):
    y = 0
    for i in range(0, len(Weight)):
        y += Weight[i]*ip[n-i]
    op[n] = y


plt.subplot(311)
plt.plot(Weight,'ro', linewidth=3)
plt.xlabel( 'weight number' )
plt.ylabel( 'weight value' )
plt.grid()

plt.subplot(312)
plt.plot( ip,'r-', linewidth=2)
plt.xlabel( 'sample length' )
plt.ylabel( 'ip value' )
plt.grid()

plt.subplot(313)
plt.plot( op,'k-', linewidth=2)
plt.xlabel( 'sample length' )
plt.ylabel( 'op value' )
plt.grid()
plt.show()

【问题讨论】:

    标签: python filter windowing


    【解决方案1】:

    你误解了一些基本的东西。加窗 sinc 滤波器设计用于分离线性组合频率;即通过加法组合的频率,而不是通过乘法组合的频率。请参阅《科学家和工程师指南》的chapter 5 数字信号处理了解更多详情。

    基于 scipy.signal 的代码将提供与您的代码类似的结果:

    from pylab import *
    import scipy.signal as signal
    
    # create an array of 1024 points sampled at 40MHz
    # [each sample is 25ns apart]
    Fs = 40e6
    nyq = Fs / 2
    T  = 1/Fs
    t  = np.arange(0,(1024*T),T)
    
    # create an ip signal sampled at Fs, using two frequencies 
    F_low  = 25e3 #  25kHz
    F_high = 1e6  #  1MHz
    ip_1 = np.sin(2*np.pi*F_low*t) + np.sin(2*np.pi*F_high*t)
    ip_2 = np.sin(2*np.pi*F_low*t) * np.sin(2*np.pi*F_high*t)
    
    Fc = 0.9e6
    Length = 101
    
    # create a low pass digital filter
    a = signal.firwin(Length, cutoff = F_high / nyq, window="hann")
    
    # create a high pass filter via signal inversion
    a = -a
    a[Length/2] = a[Length/2] + 1
    
    figure()
    plot(a, 'ro')
    
    # apply the high pass filter to the two input signals
    op_1 = signal.lfilter(a, 1, ip_1)
    op_2 = signal.lfilter(a, 1, ip_2)
    
    figure()
    plot(ip_1)
    figure()
    plot(op_1)
    figure()
    plot(ip_2)
    figure()
    plot(op_2)
    

    脉冲响应:

    线性组合输入:

    过滤后的输出:

    非线性组合输入:

    过滤后的输出:

    【讨论】:

    • 非常感谢 brentlance,我认为是这种情况 - 我已经使用基本 IIR 来隔离我想要使用非常窄带滤波器的频率 [The Scientist and Engineer's Guide to Digital 的第 19 章信号处理];并从那以后购买了那本书。再次感谢
    • 没问题,很高兴我能帮上忙。我发现那本书很有帮助。
    猜你喜欢
    • 2019-12-08
    • 2015-03-05
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 2016-12-26
    • 1970-01-01
    相关资源
    最近更新 更多