【问题标题】:Real time highpass filter实时高通滤波器
【发布时间】:2021-07-20 03:33:46
【问题描述】:

您好 在this 之后实施了一个高通滤波器。但是,我的数据不是预定义的,它是实时的。我不确定这是否正确。

def sine_generator(fs, sinefreq, duration):
    T = duration
    nsamples = int(fs * T)
    w = 2. * np.pi * sinefreq
    t_sine = np.linspace(0, T, nsamples, endpoint=False)
    y_sine = np.sin(w * t_sine)
    result = pd.DataFrame({ 
        'sine' : y_sine} ,index=t_sine)
    return result

def butter_highpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    print("Filter order is ={}, Normalized cutoff ={}".format(order, normal_cutoff))
    b, a = signal.butter(order, normal_cutoff, btype='high', analog=False)
    print(b,a)
    return b, a


# signal generation
sampling_freq = int(1e5)
cutoff_freq = 100/2*np.pi
duration = .01
data = sine_generator(sampling_freq, 10, duration) 
data['sine'] = 0.1*data['sine'] + 0.2*sine_generator(sampling_freq, int(1e3), duration)['sine'] + 0.2


t = 7 # signal.filtfilt requires atleast t values to filter. t increases as the order increases
b, a = butter_highpass(cutoff_freq, sampling_freq, order=1)
for i in range(np.shape(data.sine.values)[0]-t):
    d = data.sine.values[i:i+t+1]
    y = signal.filtfilt(b, a, d)
    print(y)

我认为这不是正确的方式。

【问题讨论】:

  • 好吧,你不能一次过滤一个元素。即使使用实时值,您也需要捆绑一组值来进行处理。收集后对这组值进行过滤。
  • 在 7 个元素长的样本中,您不会获得太多高频内容。
  • 我应该使用之前的所有数据吗,比如data.sine.values[:i+t+1]?是否有更好的实现方式来使用新旧数据进行内部更新?
  • @TimRoberts 我了解无法过滤单个元素。但我希望它能够根据旧数据进行自我更新,并随着时间的推移变得更好。
  • “好转了吗?”不,它是确定性的。给定的输入总是产生相同的输出。没有状态。我也不明白你的数字。你的数据是 10kHz,你正在做一个截止频率约为 8Hz 的高通滤波器。在获得超过 1,200 个样本之前,您甚至不会看到任何 8Hz 数据。

标签: python scipy signal-processing


【解决方案1】:

如果要过滤即将到来的数据,则必须使用过去和现在的样本应用差分方程和过滤系数。

查看详情:https://www.dsprelated.com/freebooks/filters/Difference_Equation_I.html

但是,如果您已经将这些保存的数据保存到缓冲区数组中,那么您只需在 python 中使用 signal.lfilter(b,a,input_data)。

【讨论】:

    【解决方案2】:

    让我们看一下数据。在这里,我绘制了你的整个正弦波数据集,加上高通滤波的结果:

    import numpy as np
    from scipy import signal
    import matplotlib.pyplot as plt
    
    def sine_generator(fs, sinefreq, duration):
        T = duration
        nsamples = int(fs * T)
        w = 2. * np.pi * sinefreq
        t_sine = np.linspace(0, T, nsamples, endpoint=False)
        y_sine = np.sin(w * t_sine)
        return y_sine
    
    def butter_highpass(cutoff, fs, order=5):
        nyq = 0.5 * fs
        normal_cutoff = cutoff / nyq
        print("Filter order is ={}, Normalized cutoff ={}".format(order, normal_cutoff))
        b, a = signal.butter(order, normal_cutoff, btype='high', analog=False)
        print(b,a)
        return b, a
    
    
    # signal generation
    sampling_freq = int(1e5)
    cutoff_freq = 100/2*np.pi
    duration = .01
    data = sine_generator(sampling_freq, 10, duration) 
    data = 0.1*data + 0.2*sine_generator(sampling_freq, int(1e3), duration) + 0.2
    
    plt.plot(data)
    
    t = 7 # signal.filtfilt requires atleast t values to filter. t increases as the order increases
    b, a = butter_highpass(cutoff_freq, sampling_freq, order=1)
    result = signal.filtfilt( b, a, data )
    plt.plot(result)
    plt.show()
    

    这是结果,蓝色为原始,黄色过滤,表明 DC 被过滤掉了。您只需要提供足够的样本即可使过滤生效:

    这里使用lfilter 而不是filtfilt

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2013-03-29
      • 2018-01-26
      • 2014-02-09
      • 2014-03-20
      • 1970-01-01
      相关资源
      最近更新 更多