Фильтрация правильной частоты по данным - PullRequest
1 голос
/ 09 июня 2019

Я пытаюсь отфильтровать сигнал от некоторых данных, используя функцию Баттерворта. Сигнал достаточно чистый, но я не могу его правильно отфильтровать.

Я попытался использовать разные диапазоны частот без удачи (частота составляет от 1 Гц до 1,3 Гц). Я также пытался использовать разные заказы, но не смог найти хорошего

data = [351.1475409836066,351.1475409836066,351.1475409836066,350.93877551020404,350.93877551020404,350.93877551020404,350.93877551020404,351.1475409836066,351.1475409836066,351.18367346938777,351.1475409836066,351.1475409836066,351.1475409836066,351.1475409836066,351.5702479338843,351.1475409836066,351.1475409836066,351.1475409836066,350.69387755102036,350.2834008097166,350.2834008097166,350.2834008097166,350.2834008097166,350.3225806451613,350.3225806451613,350.3225806451613,350.3225806451613,350.3225806451613,350.08064516129036,350.08064516129036,350.08064516129036,350.08064516129036,350.4878048780488,350.5263157894737,350.5263157894737,350.5263157894737,350.5263157894737,350.93877551020404,350.93877551020404,350.93877551020404,351.1475409836066,351.1475409836066,351.18367346938777,351.18367346938777,351.1475409836066,351.1475409836066,350.93877551020404,350.93877551020404,350.93877551020404,350.93877551020404,350.93877551020404,350.93877551020404,350.93877551020404,351.1475409836066,351.1475409836066,351.1475409836066,351.1475409836066,351.1475409836066,351.1475409836066,351.1475409836066,351.1475409836066,351.5702479338843,351.6049382716049,351.6049382716049,351.6049382716049,351.8181818181818,352.06611570247935,352.3140495867769,352.06611570247935,352.06611570247935,352.75,352.5,352.75,352.5,352.0331950207469,352.06611570247935,352.06611570247935,352.06611570247935,352.06611570247935,352.06611570247935,352.09876543209873,352.09876543209873,352.3140495867769,352.0331950207469,352.28215767634856,352.06611570247935,352.06611570247935,352.06611570247935,352.06611570247935,352.3140495867769,352.3140495867769,352.3140495867769,352.3140495867769,352.3140495867769,352.3140495867769,352.75,352.75,352.75,352.75,353.2217573221758,353.2217573221758,353.2217573221758,353.0,352.5311203319502,352.3140495867769,352.3140495867769,352.34567901234567,352.34567901234567,352.34567901234567,352.5619834710744,352.3140495867769,352.3140495867769,352.5619834710744,352.3140495867769,352.3140495867769,352.5619834710744,352.3140495867769,352.5619834710744,352.3140495867769,352.75,352.75,352.75,352.97071129707115,353.0,353.0,353.2217573221758,353.2217573221758,353.67088607594934,353.67088607594934,353.9240506329114,353.9240506329114,354.1525423728814,354.1525423728814,354.1525423728814,353.9240506329114,353.25,353.02904564315355,353.02904564315355,353.02904564315355,353.02904564315355,353.02904564315355,353.25,353.25,353.4728033472803,353.4728033472803,353.25,353.25,353.4728033472803,353.4728033472803,353.9240506329114,353.9240506329114,354.1525423728814,353.8983050847458,354.1276595744681,354.1276595744681,354.61538461538464,354.84978540772534,354.59227467811155,355.0862068965517,355.0862068965517,355.0862068965517,355.0862068965517,354.84978540772534,354.1525423728814,353.4728033472803,353.02904564315355,353.02904564315355,353.02904564315355,353.02904564315355,352.7800829875519,353.0,353.0,353.0,352.7800829875519,352.7800829875519,352.7800829875519,352.7800829875519,352.7800829875519,352.7800829875519,352.7800829875519,352.7800829875519,353.0,353.0,353.0,353.0,353.2217573221758,353.2217573221758,353.2217573221758,353.2217573221758,353.2217573221758,352.75,352.09876543209873,352.34567901234567,352.34567901234567,351.91836734693874,351.6734693877551,352.09876543209873,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,352.06611570247935,352.09876543209873,352.09876543209873,352.09876543209873,352.5311203319502,352.5311203319502,352.5311203319502,352.75,353.0,352.7800829875519,352.7800829875519,352.09876543209873,351.6734693877551,351.6734693877551,351.4634146341463,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,352.06611570247935,352.06611570247935,352.09876543209873,352.09876543209873,352.09876543209873,352.06611570247935,351.85185185185185,351.42857142857144,351.2195121951219,351.2195121951219,351.2195121951219,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.42857142857144,351.2195121951219,351.42857142857144,351.42857142857144,351.42857142857144,351.85185185185185,351.85185185185185,351.85185185185185,352.06611570247935,352.06611570247935,352.06611570247935,352.06611570247935,352.06611570247935,352.09876543209873,352.5311203319502,352.5311203319502,352.5311203319502,352.5,351.85185185185185,351.85185185185185,351.42857142857144,351.6734693877551,351.6734693877551,351.42857142857144,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,351.85185185185185,352.06611570247935,352.06611570247935,352.09876543209873,352.09876543209873,352.5311203319502,352.5311203319502,352.5311203319502,352.5311203319502,352.5311203319502,352.7800829875519,353.0,353.25,352.75,352.5619834710744,352.34567901234567,351.91836734693874]





from scipy.signal import butter, lfilter
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import freqz

def butter_bandpass(lowcut, highcut, fs, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = butter(order, [low, high], btype='band')
    return b, a


def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
    b, a = butter_bandpass(lowcut, highcut, fs, order=order)
    y = lfilter(b, a, data)
    return y


def run():


    # Sample rate and desired cutoff frequencies (in Hz).
    fs = 30.0
    lowcut = .9
    highcut = 1.5

    # Plot the frequency response for a few different orders.
    plt.figure(1)
    plt.clf()
    for order in [3,4,5]:
        b, a = butter_bandpass(lowcut, highcut, fs, order=order)
        w, h = freqz(b, a, worN=2000)
        plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="order = %d" % order)

    plt.plot([0, 0.5 * fs], [np.sqrt(0.5), np.sqrt(0.5)],
             '--', label='sqrt(0.5)')
    plt.xlabel('Frequency (Hz)')
    plt.ylabel('Gain')
    plt.xlim((0,2)) 
    plt.legend(loc='best')

    # Filter a noisy signal.
    T = 10.266666666666667
    nsamples = T * fs
    t = np.linspace(0, T, nsamples, endpoint=False)
    a = 0.02
    f0 = .8

    plt.figure(2)
    plt.clf()
    plt.plot(t, data, label='Noisy signal')


    y = butter_bandpass_filter(data, lowcut, highcut, fs, order=5)
    plt.plot(t, y, label='Filtered signal (%g Hz)' % f0)
    plt.xlabel('time (seconds)')
    plt.hlines([-a, a], 0, T, linestyles='--')
    plt.grid(True)
    plt.axis('tight')
    plt.legend(loc='lower left')
    plt.ylim((-40,40))   # set the ylim to bottom, top
    plt.show()


run()

Пики отфильтрованных данных явно не совпадают с пиками данных, и я не уверен, почему. Мне кажется, что исходные данные довольно чистые (вы можете визуально увидеть пики, если вы строите их).

Это может быть отдельный вопрос, но я знаю, что частота моих пиков не является регулярной и переменной (вероятно, в пределах 0,2 Гц), но, поскольку это такой большой процент от фактической Гц, боюсь, это проблема. Может ли изменчивость частоты быть причиной этой проблемы?

Спасибо!

filtered data

raw data

Таким образом, моя частота дискретизации составляла 30 Гц для необработанных данных, поэтому вес по оси x умножается на 30.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...