Bild mit NaNs in Matlab filtern?

8

Ich habe ein 2D-Array ( doubles ), das einige Daten repräsentiert, und es enthält eine Menge NaNs . Das Konturdiagramm der Daten sieht folgendermaßen aus:

Alle Leerräume sind NaNs , die graue Raute ist als Referenz vorhanden und die gefüllte Kontur zeigt die Form meiner Daten an. Wenn ich die Daten mit imfilt filtere, wird die NaNs deutlich in die Daten hineingekaut, also haben wir am Ende folgendes Ergebnis:

Sie können sehen, dass das Support-Set signifikant kontrahiert ist. Ich kann das nicht verwenden, da es in einige der interessanteren Variationen an den Kanten gekaut hat (aus Gründen, die für meine Experimente spezifisch sind, sind diese Kanten wichtig).

Gibt es eine Funktion zum Filtern innerhalb einer Insel von NaNs , die Kanten behandelt, die Kanten von rechteckigen Filterfenstern ähneln, anstatt nur die Kanten zu löschen? Wie eine nanmean -Funktion, außer falten Bilder?

Hier ist mein Filtercode:

%Vor%

und der Code zum Zeichnen des Konturdiagramms:

%Vor%

Am Mathworks-Dateiaustausch ( ndanfilter.m ) ist Code vorhanden, der sich ihm nähert zu dem, was ich will, aber ich glaube, es interpoliert nur NaNs , die auf das Innere eines Bildes gestreut werden, nicht Daten, die diesen Inseleffekt zeigen.

Hinweis: Ich habe gerade nanconv.m gefunden, was genau funktioniert Ich möchte, mit einer sehr intuitiven Verwendung (falten Sie ein Bild, NaN ignorieren, ähnlich wie nanmean funktioniert). Ich habe diesen Teil meiner angenommenen Antwort gemacht und einen Vergleich mit der Leistung der anderen Antworten aufgenommen.

Verwandte Fragen

Gaußsche Filterung eines Bildes mit Nan in Python

    
neuronet 23.04.2015, 19:53
quelle

4 Antworten

7

Die Technik, die ich am Ende benutzt habe, war die Funktion nanconv.m bei Matlabs Dateiaustausch. Es macht genau das, wonach ich gesucht habe: Es führt den Filter so aus, dass NaNs ignoriert wird, genau wie Matlabs eingebaute Funktion nanmean . Das ist schwer zu entschlüsseln aus der Dokumentation der Funktion, die ein wenig kryptisch ist.

So benutze ich es:

%Vor%

Ich füge die Funktion nanconv unten ein (sie wird von der BSD-Lizenz abgedeckt.) >). Ich werde Bilder usw. posten, wenn ich eine Chance bekomme, wollte nur posten, was ich für jemanden getan habe, der neugierig ist, was ich getan habe.

Vergleich mit anderen Antworten

Unter Verwendung der Gnovice-Lösung sehen die Ergebnisse intuitiv sehr gut aus, aber es gibt einige quantitative Blips an den Kanten, die ein Problem darstellten . In der Praxis führte die Extrapolation des Bildes über die Kanten hinaus zu vielen falschen hohen Werten an den Rändern meiner Daten.

Der Vorschlag von Krisdestruction , die fehlenden Bits durch die Originaldaten zu ersetzen, sieht auch ziemlich gut aus (besonders bei sehr kleinen Filtern) ), aber (von Entwurf) enden Sie mit ungefilterten Daten an den Rändern, was ein Problem für meine Anwendung ist.

nanconv

%Vor%     
neuronet 27.04.2015, 13:54
quelle
3

Ein Ansatz wäre, die NaN-Werte durch scatteredInterpolant (oder TriScatteredInterp in älteren MATLAB-Versionen), bevor Sie die Filtern, und dann diese Punkte wieder durch NaN-Werte ersetzen. Dies wäre vergleichbar mit dem Filtern eines vollständigen zweidimensionalen Arrays mit dem Argument 'replicate' im Gegensatz zum Argument 'symmetric' als Begrenzungsoption für imfilter (dh Sie replizieren anstelle von Werten an der gezackten NaN-Grenze) ).

So würde der Code aussehen:

%Vor%     
gnovice 23.04.2015 21:12
quelle
0

Okay, ohne Ihre Plotfunktion zu benutzen, kann ich Ihnen immer noch eine Lösung geben. Was Sie tun möchten, ist, alle neuen NaN zu finden und sie durch die ursprünglichen ungefilterten Daten zu ersetzen (vorausgesetzt, dass sie korrekt sind). Es ist zwar nicht gefiltert, aber es ist besser als die Domäne Ihres Konturenbildes zu reduzieren.

%Vor%

Ermitteln Sie mithilfe des folgenden Codes new NaN . Sie können wahrscheinlich auch die Funktion xor verwenden.

%Vor%

Dann setzt diese Zeile die Indizes in dataFiltered auf die Werte in rfVals

%Vor%

Ergebnisse

Anhand der in der Konsole gedruckten Zeilen und meines Codes können Sie sehen, dass die Anzahl von NaN in dataFiltered von 688 auf 396 reduziert wird, ebenso wie die Anzahl von NaN in rfVals .

%Vor%

Alternative Lösung 1

Sie können auch einen kleineren Filter in der Nähe der Kanten verwenden, indem Sie einen kleineren Kernel angeben und ihn danach zusammenführen. Wenn Sie jedoch nur gültige Daten mit minimalem Code wünschen, funktioniert meine Hauptlösung.

Alternative Lösung 2

Ein alternativer Ansatz besteht darin, die NaN -Werte mit Null oder einer gewünschten Konstante aufzufüllen / zu ersetzen, damit sie funktioniert, und dann zu kürzen. Für die Signalverarbeitung / Filterung werden Sie wahrscheinlich meine Hauptlösung suchen.

    
krisdestruction 23.04.2015 20:08
quelle
-3

nanfilter macht genau dasselbe mit nanconv beim Filtern, solange der Filter gleich ist. Wenn Sie die Nan-Werte vor der Verwendung von nanfilter erhalten und dann die Rückseite zur nach-gefilterten Matrix hinzufügen, erhalten Sie das gleiche Ergebnis mit dem, was Sie von nanconv mit der Option 'nanout' erhalten, solange Sie den gleichen Filter verwenden.

    
Shenjie 08.07.2015 17:25
quelle

Tags und Links