Implementierung der Leistungsdichtespektren PSD in Python
Überblick über den Code zur PSD-Extraktion
Einführung
Der folgende Code dient dazu, die Leistungsdichtespektren (Power Spectral Densities, PSD) von WAV-Dateien zu extrahieren und zu visualisieren. Die PSD zeigt, wie die Energie eines Signals über verschiedene Frequenzen verteilt ist, was in vielen Bereichen wie der Signalverarbeitung und der Akustik nützlich ist. Hier ist eine detaillierte Erklärung des Codes und seiner Funktionen:
Struktur des Codes
Importieren der Bibliotheken
import soundfile as sf
from scipy.signal import welch
import matplotlib.pyplot as plt
import os
- soundfile
: Wird verwendet, um WAV-Dateien zu lesen.
- scipy.signal.welch
: Berechnet die PSD eines Signals.
- matplotlib.pyplot
: Zum Plotten der Ergebnisse.
- os
: Zum Navigieren im Dateisystem.
Klassen
Merkmal_Extraktor
class Merkmal_Extraktor:
def __init__(self, Basisordner, Name, XAchseBeschriftung, YAchseBeschriftung, ZAchseBeschriftung):
self.Basisordner = Basisordner
self.Name = Name
self.XachseBeschriftung = XAchseBeschriftung
self.YachseBeschriftung = YAchseBeschriftung
self.ZachseBeschriftung = ZAchseBeschriftung
self.para_dict = {}
self.merkmal_daten = None
def _voller_Wellenpfad(self):
return self.Basisordner
def _lese_Wav(self, Dateipfad):
Data, Abtastrate = sf.read(Dateipfad)
return Data, Abtastrate
Diese Klasse dient als Basisklasse für das Lesen und Verarbeiten von WAV-Dateien. Sie enthält grundlegende Attribute und Methoden:
__init__
: Initialisiert die Klasse mit den notwendigen Parametern._voller_Wellenpfad
: Gibt den Basisordner zurück._lese_Wav
: Liest eine WAV-Datei und gibt die Daten und die Abtastrate zurück.
Merkmal_Extraktor_WelchPSD
class Merkmal_Extraktor_WelchPSD(Merkmal_Extraktor):
def __init__(self, Basisordner, Name='WelchPSD'):
super().__init__(Basisordner, Name, XAchseBeschriftung='Frequenzen', YAchseBeschriftung='Leistung', ZAchseBeschriftung='none')
self.para_dict['Type'] = 'WelchPSD'
self.para_dict['Type_Name'] = 'WelchPSD'
self.set_hyperparameter()
self.psd_daten = None
self.frequenzen = None
def set_hyperparameter(self, nperseg=256):
self.para_dict['Hyperpara'] = {'nperseg': nperseg}
def erstelle_aus_wav(self, Dateipfad):
Data, Abtastrate = self._lese_Wav(Dateipfad)
print(f"Abtastrate: {Abtastrate} Hz")
if len(Data.shape) > 1:
print(f"Zahl der Kanäle: {Data.shape[1]}")
else:
print("Anzahl der Kanäle: 1")
psd_Liste = []
frequenzen = None
for i in range(Data.shape[1]):
frequenzen, psd = welch(Data[:, i], fs=Abtastrate, nperseg=self.para_dict['Hyperpara']['nperseg'])
psd_Liste.append(psd)
self.frequenzen = frequenzen
self.psd_daten = psd_Liste
def merkmale_plotten(self, Titel, fig=None):
if self.psd_daten is None oder self.frequenzen ist None:
raise Exception('Keine Daten zum Plotten.')
if fig is None:
fig = plt.figure(figsize=(12, 6))
plt.title(f'Welch PSD - {Titel}')
for i, psd in enumerate(self.psd_daten):
plt.plot(self.frequenzen, psd, label=f'{Titel} - Kanal {i+1}')
plt.xlabel('Frequenz (Hz)')
plt.ylabel('Leistungsdichtespektrum (PSD)')
plt.legend()
plt.tight_layout()
Diese Klasse erbt von Merkmal_Extraktor
und fügt spezifische Methoden zur Berechnung und zum Plotten der PSD hinzu:
__init__
: Initialisiert die Klasse und setzt Hyperparameter.set_hyperparameter
: Setzt den Hyperparameter für die PSD-Berechnung.erstelle_aus_wav
: Liest eine WAV-Datei, berechnet die PSD und speichert die Ergebnisse.merkmale_plotten
: Plottet die gespeicherten PSD-Daten.
Funktion zum Verarbeiten aller Dateien
def alle_dateien_verarbeiten(Basisordner):
for ID_Ordner in sorted(os.listdir(Basisordner)):
ID_Pfad = os.path.join(Basisordner, ID_Ordner)
if os.path.isdir(ID_Pfad):
print(f'Verzeichnis wird verarbeitet: {ID_Pfad}')
fig = plt.figure(figsize=(12, 6))
plt.title(f'Welch PSD - {ID_Ordner}')
Kategorien = ['abnormal', 'normal']
for Kategorie in Kategorien:
Kategorie_ordner = os.path.join(ID_Pfad, Kategorie)
alle_datein = [os.path.join(Kategorie_ordner, f) for f in os.listdir(Kategorie_ordner) if f.endswith('.wav')]
for Datei_pfad in alle_datein:
print(f'Verarbeitung --> {Datei_pfad}')
Extraktor = Merkmal_Extraktor_WelchPSD(Basisordner)
try:
Extraktor.erstelle_aus_wav(Datei_pfad)
Extraktor.merkmale_plotten(Titel=f'{Kategorie.capitalize()} - {os.path.basename(Datei_pfad)}', fig=fig)
except ValueError as e:
print(f'Fehler bei der Verarbeitung von {Datei_pfad}: {e}')
plt.show()
return
Diese Funktion durchläuft das Basisverzeichnis, verarbeitet alle WAV-Dateien und plottet die Ergebnisse:
alle_dateien_verarbeiten
: Durchläuft alle Unterverzeichnisse und Dateien im Basisordner, liest die WAV-Dateien und plottet die PSDs für jede ID in einer einzigen Figur.
Main-Funktion
if __name__ == "__main__":
Basisordner = r'C:\Users\Andreas\Desktop\Projekt\data\6_dB_valve\valve'
alle_dateien_verarbeiten(Basisordner)
Das Hauptskript ruft die alle_dateien_verarbeiten
Funktion auf, um alle Dateien im angegebenen Basisordner zu verarbeiten.
Zusammenfassung
Der Code dient dazu, die PSD von WAV-Dateien zu berechnen und zu visualisieren. Er durchläuft einen Basisordner mit Unterverzeichnissen, liest die WAV-Dateien, berechnet die PSD mithilfe der Welch-Methode und plottet die Ergebnisse für jede ID in einer einzigen Figur. Die Implementierung ist modular aufgebaut, wobei Klassen zur Organisation und Wiederverwendbarkeit des Codes beitragen.