Answers:
使用黄油 功能设计的滤波器的频率响应为:
但是没有理由将滤波器限制为恒定的单调滤波器设计。如果您希望阻带更高的衰减和更陡峭的过渡带,则可以使用其他选项。有关使用iirdesing指定过滤器的更多信息,请参见this。如黄油设计的频率响应图所示,截止频率(-3dB点)离目标很远。可以通过在过滤之前进行下采样来缓解这种情况(使用如此狭窄的过滤器(带宽的2%),设计功能将面临一段艰难的时期)。让我们看一下用指定的截止频率过滤原始采样率。
import numpy as np
from scipy import signal
from matplotlib import pyplot as plt
from scipy.signal import fir_filter_design as ffd
from scipy.signal import filter_design as ifd
# setup some of the required parameters
Fs = 1e9 # sample-rate defined in the question, down-sampled
# remez (fir) design arguements
Fpass = 10e6 # passband edge
Fstop = 11.1e6 # stopband edge, transition band 100kHz
Wp = Fpass/(Fs) # pass normalized frequency
Ws = Fstop/(Fs) # stop normalized frequency
# iirdesign agruements
Wip = (Fpass)/(Fs/2)
Wis = (Fstop+1e6)/(Fs/2)
Rp = 1 # passband ripple
As = 42 # stopband attenuation
# Create a FIR filter, the remez function takes a list of
# "bands" and the amplitude for each band.
taps = 4096
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
# The iirdesign takes passband, stopband, passband ripple,
# and stop attenuation.
bc, ac = ifd.iirdesign(Wip, Wis, Rp, As, ftype='ellip')
bb, ab = ifd.iirdesign(Wip, Wis, Rp, As, ftype='cheby2')
如前所述,由于我们试图过滤很小百分比的带宽,因此过滤器将不会出现急剧的截止。在这种情况下,通过低通滤波器,我们可以减少带宽以获得外观更好的滤波器。python / scipy.signal重采样功能可用于减少带宽。
请注意,重采样功能将执行过滤以防止混叠。也可以进行预过滤(以减少混叠),在这种情况下,我们可以简单地按100进行重采样并完成操作,但问题是创建过滤器。在此示例中,我们将采样降低25并创建一个新的过滤器
R = 25; # how much to down sample by
Fsr = Fs/25. # down-sampled sample rate
xs = signal.resample(x, len(x)/25.)
如果我们更新FIR滤波器的设计参数,则新的响应是。
# Down sampled version, create new filter and plot spectrum
R = 25. # how much to down sample by
Fsr = Fs/R # down-sampled sample rate
Fstop = 11.1e6 # modified stopband
Wp = Fpass/(Fsr) # pass normalized frequency
Ws = Fstop/(Fsr) # stop normalized frequency
taps = 256
br = ffd.remez(taps, [0, Wp, Ws, .5], [1,0], maxiter=10000)
对降采样数据进行操作的滤波器具有更好的响应。使用FIR滤波器的另一个好处是您将具有线性相位响应。
filtfilt
该a
参数的要求。
这样行吗?
from __future__ import division
from scipy.signal import butter, lfilter
fs = 1E9 # 1 ns -> 1 GHz
cutoff = 10E6 # 10 MHz
B, A = butter(1, cutoff / (fs / 2), btype='low') # 1st order Butterworth low-pass
filtered_signal = lfilter(B, A, signal, axis=0)
您说得对,但是文档不是很完整。看起来像是butter
的包装器iirfilter
,对此有更好的记录:
N:int过滤器的顺序。Wn:array_like一个给出临界频率的标量或长度为2的序列。
不过,其中大部分内容都是从matlab克隆的,因此您也可以查看其文档:
归一化截止频率Wn必须为0到1之间的数字,其中1对应于奈奎斯特频率,每个样本π弧度。
更新:
我添加了这些功能的文档。:) Github使它变得容易。
这个FIR滤波器的效果很好。请注意,它两次应用了滤波器,分别进行“正向”和“反向”,以补偿信号偏移(filtfilt
功能不起作用,不知道为什么):
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)
secondpass = scipy.signal.lfilter(b, a, firstpass[::-1])[::-1]
return secondpass
THIS是我进行此代码的地方以及可以通过带通和高通滤波器示例的过滤器设计和使用的绝佳资源。
我没有评论权...
@endolith:除了使用scipy.signal.filtfilt(B,A,x)之外,我使用的其他方法与之相同,其中x是要过滤的输入向量-例如numpy.random.normal(size =(N))。 filtfilt对信号进行正向和反向传递。为了完整起见(大多数与@endolith相同):
import numpy as np
import scipy.signal as sps
input = np.random.normal(size=(N)) # Random signal as example
bz, az = sps.butter(FiltOrder, Bandwidth/(SamplingFreq/2)) # Gives you lowpass Butterworth as default
output = sps.filtfilt(bz, az, input) # Makes forward/reverse filtering (linear phase filter)
@heltonbiker也建议使用filtfilt,它需要系数数组。如果您需要在复杂的基带上执行带通滤波,则需要更复杂的配置,但这在这里似乎不是问题。