2009-05-08 6 views
3

Die Matlab FAQ finden, beschreibt eine einzeilige Methode, die lokalen maximas für die Suche:eine ungefähre lokale maximas mit verrauschten Daten in Matlab

index = find(diff(sign(diff([0; x(:); 0]))) < 0); 

Aber ich glaube, das funktioniert nur, wenn die Daten mehr oder weniger glatt ist. Angenommen, Sie haben Daten, die in kleinen Intervallen auf und ab springen, aber immer noch ungefähre lokale Maxima haben. Wie würdest du diese Punkte finden? Sie könnten den Vektor in n Stücke teilen und den größten Wert nicht am Rand von jedem finden, aber es sollte eine elegantere und schnellere Lösung geben.

Eine One-Line-Lösung wäre auch toll.

Bearbeiten: Ich arbeite mit lauten biologischen Bildern, die ich in verschiedene Abschnitte zu teilen versuche.

+0

Da Sie Ihre Frage aktualisiert haben, um zu sagen, dass Sie mit Bildern arbeiten, ist die obige Maxima-Befund-Gleichung (die für Vektoren spezifischer ist) möglicherweise nicht ideal für Sie. Ich würde vorschlagen, die Bildverarbeitungs-Toolbox in MATLAB zu betrachten, wenn Sie Zugriff darauf haben. Es kann einige Operationen geben, die dir helfen. Geben Sie einfach "Hilfe Bilder" in MATLAB ein, um die Funktionsliste auszuprobieren. – gnovice

Antwort

2

Je nachdem, was Sie wollen, ist es oft hilfreich, die verrauschten Daten zu filtern. Schauen Sie sich MEDFILT1, oder CONV zusammen mit FSPECIAL. Bei dem letztgenannten Ansatz werden Sie wahrscheinlich das gleiche Argument für CONV und einen von FSPECIAL erstellten Gauß'schen Filter verwenden wollen.

Nachdem Sie die Filterung durchgeführt haben, führen Sie sie durch den Maxima-Finder.

EDIT:Laufzeitkomplexität

ist der Eingangsvektor Länge X Lassen Sie sagen, hat und die Filterkernlänge K.

Der Medianfilter, indem Sie einen laufenden Insertionsort arbeiten kann, so dass es sollte O sein (X K + K log K). Ich habe den Quellcode nicht angeschaut und andere Implementierungen sind möglich, aber grundsätzlich sollte es O (X K) sein.

Wenn K klein ist, verwendet Conv einen einfachen O (X * K) -Algorithmus. Wenn X und K fast gleich sind, ist es schneller, eine schnelle Fourier-Transformation zu verwenden. Diese Implementierung ist O (X log X + K log K). Matlab ist intelligent genug, um automatisch den richtigen Algorithmus abhängig von den Eingabegrößen auszuwählen.

+0

Wunderbar! Mein Lernfreund, wie zeitaufwendig ist das? –

3

Ich bin mir nicht sicher, mit welcher Art von Daten Sie es zu tun haben, aber hier ist eine Methode, die ich für die Verarbeitung von Sprachdaten verwendet habe, die Ihnen helfen könnte, lokale Maxima zu finden. Es verwendet drei Funktionen aus der Signal Processing Toolbox: HILBERT, BUTTER und FILTFILT.

data = (...the waveform of noisy data...); 
Fs = (...the sampling rate of the data...); 
[b,a] = butter(5,20/(Fs/2),'low'); % Create a low-pass butterworth filter; 
            % adjust the values as needed. 
smoothData = filtfilt(b,a,abs(hilbert(data))); % Apply a hilbert transform 
               % and filter the data. 

Sie würden dann Ihre Maxima Befund auf smoothData zuführen. Die Verwendung von HILBERT erzeugt zuerst eine positive Hüllkurve auf den Daten, dann verwendet FILTFILT die Filterkoeffizienten von BUTTER, um die Datenhüllkurve tief zu filtern.

Für ein Beispiel, wie diese Verarbeitung funktioniert, hier sind einige Bilder, die die Ergebnisse für ein Segment der aufgezeichneten Sprache zeigen. Die blaue Linie ist das ursprüngliche Sprachsignal, die rote Linie ist die Hüllkurve (erhalten mit HILBERT) und die grüne Linie ist das Tiefpass-Ergebnis. Die untere Abbildung ist eine vergrößerte Version der ersten.

alt text

etwas zufällig eventuell helfen:

Dies ist eine zufällige Idee war ich zuerst hatte ... Sie könnten versuchen, den Prozess zu wiederholen, indem sie die maximas der maximas finden:

index = find(diff(sign(diff([0; x(:); 0]))) < 0); 
maxIndex = index(find(diff(sign(diff([0; x(index); 0]))) < 0)); 

In Abhängigkeit vom Signal-Rausch-Verhältnis wäre es jedoch unklar, wie oft es wiederholt werden müsste, um die lokalen Maxima zu erhalten, an denen Sie interessiert sind. Es ist nur ein Rando m nicht filternde Option zu versuchen. =)

MAXIMA FINDING:

Gerade falls Sie neugierig ist, ein weiterer einzeiligen Maxima-Suchalgorithmus, die ich (zusätzlich zu dem einen gesehen haben Sie aufgelistet) ist:

index = find((x > [x(1) x(1:(end-1))]) & (x >= [x(2:end) x(end)])); 
+0

Du bist großartig! filtifilt ist "Zero-phase digital filtering" - bedeutet das, dass es garantiert, dass High-Points in gefilterten Daten Höhepunkte in den Originaldaten sind? Siehe meine Bearbeitung der Frage auch. –

+0

+1 nur für die hübschen Graphen. :) –

+1

@Joe S: nein. Nullphasenfilterung bedeutet nur, dass wenn Sie reine Sinuswellen als Eingänge haben, die Ausgänge die gleiche Phase haben.filtfilt funktioniert, indem es zeitlich vorwärts und dann zeitlich rückwärts filtert (etwas, was bei der Echtzeit-Signalverarbeitung nicht möglich ist), um Zeitverzögerungen durch Tiefpassfilter auszugleichen. –

1

Wenn Ihre Daten stark nach oben und unten springen, hat die Funktion viele lokale Maxima. Also ich nehme an, dass Sie nicht alle lokalen Maxima finden wollen. Aber wie lauten Ihre Kriterien für ein lokales Maximum? Wenn Sie ein Kriterium haben, kann man dafür ein Schema oder einen Algorithmus entwerfen.

Ich vermute jetzt, dass Sie vielleicht zuerst einen Tiefpassfilter auf Ihre Daten anwenden sollten und dann die lokalen Maxima finden. Obwohl die Positionen der lokalen Maxima nach der Filterung möglicherweise nicht genau denen vorher entsprechen.

1

Es gibt zwei Möglichkeiten, ein solches Problem anzuzeigen. Man kann dies als primär ein Glättungsproblem betrachten, indem man ein Filtertool verwendet, um die Daten zu glätten, und erst anschließend mit einer Vielzahl von Interpolanten, vielleicht einem interpolierenden Spline, zu interpolieren. Das Finden eines lokalen Maximums eines interpolierenden Splines ist einfach genug. (Beachten Sie, dass Sie hier generell einen echten Spline verwenden sollten, nicht einen Pchip-Interpolant. Pchip, die Methode, die bei der Angabe eines "kubischen" Interpolanten in interp1 verwendet wird, lokalisiert einen lokalen Minimierer, der zwischen zwei Datenpunkten liegt, nicht genau.)

Der andere Ansatz zu einem solchen Problem ist einer, den ich bevorzuge. Hier verwendet man ein Spline-Modell der kleinsten Quadrate, um sowohl die Daten zu glätten als auch einen Approximanten anstelle eines Interpolanten zu erzeugen. Ein solcher Spline mit der kleinsten Fehlerquadrate hat den Vorteil, dem Benutzer eine große Kontrolle zu ermöglichen, um sein Wissen über das Problem in das Modell einzubringen. Zum Beispiel hat der Wissenschaftler oder Ingenieur oft Informationen, wie Monotonie, über den zu untersuchenden Prozess. Dies kann in ein Spline-Modell der kleinsten Quadrate eingebaut werden. Eine weitere verwandte Option ist die Verwendung eines glättenden Splines. Sie können auch mit in sie eingebauten Regularisierungsbedingungen gebaut werden. Wenn Sie die Spline-Toolbox haben, wird spap2 nützlich für ein Spline-Modell sein. Dann findet Fnmin einen Minimierer. (Ein Maximierer wird leicht aus einem Minimierungscode erhalten.)

Glättungsschemata, die Filtermethoden verwenden, sind im Allgemeinen am einfachsten, wenn die Datenpunkte gleichmäßig beabstandet sind. Ungleiche Abstände könnten für das Spline-Modell der kleinsten Quadrate pushen. Auf der anderen Seite kann die Knotenplatzierung ein Problem bei den Splines mit kleinsten Quadraten sein. In diesem Zusammenhang möchte ich darauf hinweisen, dass beide Ansätze sinnvoll sind und zu tragfähigen Ergebnissen führen können.