Ich versuche, ein verrauschtes Herzfrequenzsignal mit Python zu filtern. Da die Herzfrequenz niemals über 220 Schlägen pro Minute liegen sollte, möchte ich alle Geräusche über 220 Schlägen pro Minute herausfiltern. Ich wandelte 220 / Minute in 3,66666666 Hertz um und wandelte dieses Hertz dann in rad / s um, um 23,0383461 rad / s zu erhalten.
Die Abtastfrequenz des Chips, der Daten aufnimmt, beträgt 30 Hz, daher habe ich diese in rad / s konvertiert, um 188,495559 rad / s zu erhalten.
Nachdem ich einige Dinge online nachgeschlagen hatte, fand ich einige Funktionen für einen Bandpassfilter, den ich in einen Tiefpass verwandeln wollte. Hier ist der Link zum Bandpasscode , also habe ich ihn folgendermaßen konvertiert:
from scipy.signal import butter, lfilter
from scipy.signal import freqs
def butter_lowpass(cutOff, fs, order=5):
nyq = 0.5 * fs
normalCutoff = cutOff / nyq
b, a = butter(order, normalCutoff, btype='low', analog = True)
return b, a
def butter_lowpass_filter(data, cutOff, fs, order=4):
b, a = butter_lowpass(cutOff, fs, order=order)
y = lfilter(b, a, data)
return y
cutOff = 23.1 #cutoff frequency in rad/s
fs = 188.495559 #sampling frequency in rad/s
order = 20 #order of filter
#print sticker_data.ps1_dxdt2
y = butter_lowpass_filter(data, cutOff, fs, order)
plt.plot(y)
Ich bin sehr verwirrt darüber, weil ich ziemlich sicher bin, dass die Butterfunktion die Grenz- und Abtastfrequenz in rad / s berücksichtigt, aber ich scheine eine seltsame Ausgabe zu bekommen. Ist es tatsächlich in Hz?
Zweitens, was ist der Zweck dieser beiden Zeilen:
nyq = 0.5 * fs
normalCutoff = cutOff / nyq
Ich weiß, dass es um Normalisierung geht, aber ich dachte, der Nyquist war das Zweifache der Abtastfrequenz, nicht die Hälfte. Und warum benutzt du den Nyquist als Normalisierer?
Kann jemand mehr darüber erklären, wie man mit diesen Funktionen Filter erstellt?
Ich habe den Filter gezeichnet mit:
w, h = signal.freqs(b, a)
plt.plot(w, 20 * np.log10(abs(h)))
plt.xscale('log')
plt.title('Butterworth filter frequency response')
plt.xlabel('Frequency [radians / second]')
plt.ylabel('Amplitude [dB]')
plt.margins(0, 0.1)
plt.grid(which='both', axis='both')
plt.axvline(100, color='green') # cutoff frequency
plt.show()
und habe dies bekommen, was bei 23 rad / s eindeutig nicht abschneidet:
quelle
freqz
. Ich mag einen glatten Plot mit einer übermäßigen Auflösung, die ich ein wenig vergrößern kann, ohne den Plot neu generieren zu müssen, und 8000 ist groß genug, um dies in den meisten Fällen zu erreichen.