Diskrete Wavelet-Transformation - Visualisierung der Beziehung zwischen zerlegten Detailkoeffizienten und Signal


12

Ich versuche, die Beziehung zwischen den Detailkoeffizienten der diskreten Wavelet-Transformation (DWT) und dem ursprünglichen Signal / seiner Rekonstruktion direkt zu visualisieren. Ziel ist es, ihre Beziehung intuitiv darzustellen. Ich möchte fragen (siehe Fragen unten): Wenn die Idee und der Prozess, die ich mir ausgedacht habe, bisher korrekt sind und wenn ich Recht habe, dass es besser ist, die Näherung der 1. Ebene vom ursprünglichen Signal zu subtrahieren, bevor ich ihre Beziehung visualisiere .

Minimales Beispiel

Hier ist das minimale Beispiel, auf das ich meine Erklärung stütze, indem ich die EKG-Beispieldaten von Pythonpywavelets mit 1024 Werten als einfaches 1D-Signal verwende:

import pywt
import pywt.data
import numpy as np
import matplotlib.pyplot as plt

x = pywt.data.ecg()
plt.plot(x)
plt.legend(['Original signal'])

Originalsignal

Die Zerlegung erfolgt mit einem Symmlet 5 mit insgesamt 6 Stufen:

w = pywt.Wavelet('sym5')
plt.plot(w.dec_lo)
coeffs = pywt.wavedec(x, w, level=6)

Die (verlustbehaftete) Rekonstruktion des Signals funktioniert wie erwartet, wenn absichtlich Detailkoeffizienten höherer Pegel weggelassen werden (Signale werden der Einfachheit halber auf einer einheitlichen x-Skala [0,1] aufgezeichnet):

def reconstruction_plot(yyy, **kwargs):
    """Plot signal vector on x [0,1] independently of amount of values it contains."""
    plt.plot(np.linspace(0, 1, len(yyy)), yyy, **kwargs)

reconstruction_plot(pywt.waverec(coeffs, w)) # full reconstruction 
#reconstruction_plot(pywt.waverec(coeffs[:-1] + [None] * 1, w)) # leaving out detail coefficients up to lvl 5
#reconstruction_plot(pywt.waverec(coeffs[:-2] + [None] * 2, w)) # leaving out detail coefficients up to lvl 4
#reconstruction_plot(pywt.waverec(coeffs[:-3] + [None] * 3, w)) # leaving out detail coefficients up to lvl 3
reconstruction_plot(pywt.waverec(coeffs[:-4] + [None] * 4, w)) # leaving out detail coefficients up to lvl 2
#reconstruction_plot(pywt.waverec(coeffs[:-5] + [None] * 5, w)) # leaving out detail coefficients up to lvl 1
reconstruction_plot(pywt.waverec(coeffs[:-6] + [None] * 6, w)) # leaving out all detail coefficients = reconstruction using lvl1 approximation only
plt.legend(['Full reconstruction', 'Reconstruction using detail coefficients lvl 1+2', 'Reconstruction using lvl 1 approximation only'])

Rekonstruiertes Signal

Die obige DWT ergibt einen Näherungsvektor der Stufe 1 von 24 Werten, einen Detailkoeffizientenvektor der Stufe 1 von 24 Werten, einen Detailvektor der Stufe 2 von 40 Werten, eine Stufe 3 von 72 Werten, eine Stufe 4 von 135 Werten, eine Stufe 5 von 262 Werten und eine Stufe 6 von 516 Werten:

plt.stem(coeffs[1]); plt.legend(['Lvl 1 detail coefficients'])
plt.stem(coeffs[2]); plt.legend(['Lvl 2 detail coefficients'])
plt.stem(coeffs[3]); plt.legend(['Lvl 3 detail coefficients'])
plt.stem(coeffs[4]); plt.legend(['Lvl 4 detail coefficients'])
plt.stem(coeffs[5]); plt.legend(['Lvl 5 detail coefficients'])
plt.stem(coeffs[6]); plt.legend(['Lvl 6 detail coefficients'])

Detailkoeffizienten der Stufe 1 Detailkoeffizienten der Stufe 2 Detailkoeffizienten der Stufe 3 Detailkoeffizienten der Stufe 4 Detailkoeffizienten der Stufe 5 Detailkoeffizienten der Stufe 6

Es scheint, dass wir in den Originalsignalen klare Muster um die Spitzen sehen (achten Sie auch auf die y-Skala der obigen Diagramme).

Nun zu meinen Fragen:

  1. Ist es richtig, dass wir diese Koeffizienten direkt mit dem Signal in Beziehung setzen können ? Die Amplitude des Koeffizienten entspricht der Amplitude, mit der das Wavelet im Signal auftritt (y-Achse), und die Position des Koeffizienten entspricht der Zeit (x-Achse). Oder gibt es etwas dazwischen, das wir berücksichtigen müssen?
  2. Nach dem DWT bleibt die endgültige lvl1-Näherung erhalten. Ist es sinnvoll, die Beziehung der Detailkoeffizienten zum Originalsignal nicht zu visualisieren, sondern zum Originalsignal abzüglich der lvl1-Näherung? (Ich weiß, dass ich höchstwahrscheinlich auch die Beziehung zwischen Koeffizienten und Signal sehen würde, ohne dies zu tun, siehe z. B. Diagramme unten. Es ist nur dafür sinnvoll oder nicht. Sollte es für lvl1-Detailkoeffizienten sinnvoll sein, könnte es auch sinnvoll sein für lvl2-Detailkoeffizienten, die mit dem ursprünglichen Signal abzüglich der lvl2-Näherung verglichen werden sollen, richtig?). Ein Beispiel:

    # Reconstruction of signal using just lvl1 approximation
    approx_lvl1 = pywt.waverec(coeffs[:-6] + [None] * 6, w)
    # interpolate to original amount of samples (necessary due to numeric solution of transformation not yielding same amount of values)
    approx_lvl1_interp = np.interp(x=np.arange(0, 1024), xp=np.linspace(0, 1024, len(approx_lvl1)), fp=approx_lvl1)
    x_without_lvl1approx = x - approx_lvl1_interp
    
  3. Die direkte Visualisierung der Beziehung zwischen Detailkoeffizienten und Signal, die ich verwende, zeichnet nur das Signal und die Koeffizienten auf einer x-Achse von [0,1]. Dies sollte konzeptionell gültig sein, aber ich bin mir nicht sicher, ob ich tatsächlich einen Versatz zu den Rändern benötigen würde (z. B. erster und letzter Koeffizient des Vektors, der nicht ganz am Anfang oder Ende des Signals positioniert ist):

    def reconstruction_stem(yyy, **kwargs):
        """Plot coefficient vector on x [0,1] independently of amount of values it contains."""
        plt.stem(np.linspace(0, 1, len(yyy)), yyy, **kwargs)
    
    reconstruction_plot(x, color='orange')
    reconstruction_plot(x_without_lvl1approx, color='red')
    reconstruction_stem(coeffs[1])
    plt.legend(['Original signal', 'Original signal - lvl1 approximation', 'Detail coefficients'])
    

Beziehung zwischen den Detailkoeffizienten lvl1 und dem Signal Beziehung zwischen den Detailkoeffizienten lvl2 und dem Signal Beziehung zwischen den Detailkoeffizienten lvl3 und dem Signal Beziehung zwischen den Detailkoeffizienten lvl4 und dem Signal Beziehung zwischen den Detailkoeffizienten lvl5 und dem Signal Beziehung zwischen den Detailkoeffizienten lvl6 und dem Signal

Gibt es eine intuitive Erklärung für die starken Koeffizienten, die sich nicht direkt an den Positionen der Peaks in den Originaldaten befinden (z. B. auf Stufe 1 die niedrigste (stärkste negative) bei etwa 0,25 sowie die höchste (stärkste positive) bei etwa 0,75 )? Obwohl es ein klares Muster gibt (positive Verzögerung + negative Amplitude, negative Verzögerung + positive Amplitude), scheinen diese für mich ein bisschen "weit weg" zu sein. Aber dafür gibt es wahrscheinlich eine gute Erklärung.

Danke für die Antwort!


Sie haben keine Antwort erhalten, aber Ihre Frage selbst ist ein gutes Tutorial für die Implementierung der Wavelet-Analyse in Python. Vielen Dank!
Farzad

Antworten:


0

Ich fange erst jetzt an, mich mit Wavelets zu beschäftigen, und kämpfe immer noch mit sehr grundlegenden Fragen wie "Wie wählt man aus der Menge der verfügbaren Wavelets aus?" (Dies hängt wahrscheinlich mit der Anzahl der Ebenen zusammen, die Sie benötigen, um "gut genug" zu erreichen. Darstellung) und "Was ist das Problem beim Entrauschen mit Wavelets", weil ich mit geraden Gaußschen Entrauschungs- oder Medianfiltern in der Lage zu sein scheint, bessere Ergebnisse für meinen Datentyp zu erzielen. Aber ich schweife ab....

Eine Sache, die ich oben bemerkt habe, ist, dass Ihre Level-Nummerierung nicht mit dem übereinstimmt, was ich für die üblichen Wavelet-Konventionen halte. Insbesondere sind Koeffizienten [0] die Approximationsamplituden auf der letzten Ebene, in Ihrem Fall sind 6 Koeffizienten [1] die Detailamplitude auf Ebene 6 Koeffizienten [2] sind die Detailamplitude auf Ebene 5 ... Koeffizienten [6] sind die Detailamplitude auf Stufe 1

Ihre Rekonstruktionen stammen also nur von Level 5 und 6, nicht von Level 1 und 2, wie in Ihren Plots angegeben.

=========

Update: Ich habe mehr mit Ihrem Code herumgespielt und ich denke, Ihre Idee, die Korrelation zwischen Koeffizienten und Signalmerkmalen zu veranschaulichen, ist solide, aber nicht perfekt. Ich habe ein bisschen mit Ihrem Code herumgespielt, um dies besser zu veranschaulichen, siehe unten. Beachten Sie, dass ich bei jedem Schritt die Koeffizienten auf die Größe des Signals neu skaliere. Dies ermöglicht es einem, auch über das Konzept der Schwellenwertbildung zu sprechen.

import pywt
import pywt.data
import numpy as np
import matplotlib.pyplot as plt

plt.close('all')

def reconstruction_plot(yyy, **kwargs):
    """Plot signal vector on x [0,1] independently of amount of values it contains."""
    #plt.figure()
    #plt.plot(np.linspace(0, 1, len(yyy)), yyy, **kwargs)
    ym = np.median(yyy)
    plt.plot(np.linspace(0, 1., num=len(yyy)), yyy-ym, **kwargs)


def reconstruction_stem(yyy, xmax, **kwargs):
    """Plot coefficient vector on x [0,1] independently of amount of values it contains."""
    ymax = yyy.max()
    plt.stem(np.linspace(0, 1., num=len(yyy)), yyy*(xmax/ymax), **kwargs)


x = pywt.data.ecg()
w = pywt.Wavelet('sym5')
nl = 6
coeffs = pywt.wavedec(x, w, level=nl)


'''
plt.figure()
plt.stem(coeffs[1]); plt.legend(['Lvl 6 detail coefficients'])
plt.figure()
plt.stem(coeffs[2]); plt.legend(['Lvl 5 detail coefficients'])
plt.figure()
plt.stem(coeffs[3]); plt.legend(['Lvl 4 detail coefficients'])
plt.figure()
plt.stem(coeffs[4]); plt.legend(['Lvl 3 detail coefficients'])
plt.figure()
plt.stem(coeffs[5]); plt.legend(['Lvl 2 detail coefficients'])
plt.figure()
plt.stem(coeffs[6]); plt.legend(['Lvl 1 detail coefficients'])
'''


xmax = x.max()
for i in range(nl):
    plt.figure()
    reconstruction_plot(x) # original signal 
    #reconstruction_plot(pywt.waverec(coeffs, w)) # full reconstruction 
    reconstruction_plot(pywt.waverec(coeffs[:i+2] + [None] * (nl-i-1), w)) # partial reconstruction 
    reconstruction_stem(coeffs[i+1], xmax, markerfmt ='none', linefmt='r-')
    #plt.legend(['Original', 'Full reconstruction', ('Rec to lvl %d')%(nl-i), ('Details for lvl %d')%(nl-i)])
    plt.legend(['Original', ('Rec to lvl %d')%(nl-i), ('Details for lvl %d')%(nl-i)])
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.