Wie kann ich einen Tiefpassfilter verwenden, indem ich nur die Spitzendaten reduziere?

16

Ich habe ein 2D-Bild, das ich filtern möchte, mit diesen Einschränkungen / Qualitätsmetriken:

  1. Ich kann dem Bild kein Licht "hinzufügen", daher sollte jedes Pixel im Ergebnis <= das entsprechende Pixel in der Eingabe sein.
  2. Die Tiefpass-Grenzfrequenz sollte ein Parameter sein, mit dem experimentiert werden soll
  3. Das wiederholte Anwenden dieses Filters sollte das Ergebnis nicht wesentlich verändern.
  4. Die Zeit, die benötigt wird, um diesen Algorithmus auszuführen (5 Minuten für ein 5MPix-Image scheinen angemessen)
  5. Minimierung der Lichtmenge, die weggefiltert wird.

Im Folgenden sind einige Ansätze aufgeführt, die ich zusammen mit ihren Nachteilen ausprobiert habe:

  1. Gauß-Filter wie gewohnt, dann ziehen Sie das Ergebnis nach unten, um die Bedingung 1 zu erfüllen. Dies entspricht sehr gut den ersten 3 Punkten, reduziert jedoch viel mehr Licht als nötig.

  2. Anpassen von "Aufwärts" -Parabeln durch die "Tief" -Punkte und "Abwärts" -Parabeln zwischen ihnen, um zu glätten. Dies funktioniert in 1D sehr gut, aber wenn Sie es zuerst horizontal und dann vertikal anwenden, werden in 2D schlechte Ergebnisse erzielt. Es dauert viel länger, aber nicht zu lange für meine Bewerbung. Durch wiederholtes Anwenden dieses Filters wird das Ergebnis jedoch drastisch geändert. Wenn der (1D) -Eingang eine perfekte "Abwärts" -Parabel ist (die überhaupt nicht gefiltert werden sollte), wird er durch 2 "Aufwärts" -Parabeln ersetzt, die am Anfang / Ende sitzen.

  3. Verwenden einer anderen Form von 2D-Grundfunktionen und lineares Lösen, um die optimalen Parameter zu finden. Dies ist eine Idee, die derzeit noch nicht implementiert / getestet ist.

Mein Erfahrungsbereich in der Signalverarbeitung ist fast ausschließlich die Bildverarbeitung, daher hoffe ich, mit dem Input von Experten, die in anderen Bereichen der Signalverarbeitung tätig sind, Alternativen zu diesem Problem zu finden.

Update 18.08.2011

Auf der Grundlage der aktuellen Reaktionen habe ich beschlossen, die Dinge etwas klarer zu gestalten, indem ich Diagramme eines typischen Inputs und die Ergebnisse der drei ursprünglich beschriebenen Ansätze + der Vorschläge, die ich bisher erhalten habe, hinzufügte. Zum einfachen Vergleich habe ich in diesen Beispielen nur 1D-Filterung verwendet.

Eingabedaten: Eingabedaten

Gauß-Filter + senken, um die Anforderung (1) zu erfüllen.
Sie können sehen, dass ein Herunterfahren zu unnötigen Lichteinsparungen auf der rechten Seite führt. Gaußsche gefiltert

Parabeln
Was mich betrifft, ist dies ziemlich gut, leider lässt es sich nicht perfekt in 2D übersetzen, wenn zuerst horizontal, dann vertikal angewendet wird. In diesem Fall sehe ich auch, dass ich die angepassten Parabeln in Gleitkommaauflösung auswerten kann, was ein kleiner Vorteil ist, aber nicht unbedingt erforderlich. Parabelbefestigung

Graustufenerosion
Auf Anregung von rwong habe ich Graustufenerosion ausprobiert. Ich habe ein Strukturierungselement mit der gleichen parabolischen Form wie meine "angepassten" Parabeln verwendet. Das Ergebnis ist nahezu identisch, das sieht also vielversprechend aus. Es gibt jedoch noch einige Probleme: 1. Mein Strukturierungselement war nicht "groß genug" (obwohl es bereits 801 Pixel breit war) 1. Ich habe nur "aufwärts" -Parabeln, keine "abwärts" -Parabeln, um den Übergang von einer Parabel zu glätten zum nächsten. Graustufenerosion

Medianfilterung
Nur der Vollständigkeit halber ist es nicht wirklich das, was ich will. Medianfilter

Rohdaten
Ich habe die Rohdaten + die verschiedenen Python-Befehle in den Pastebin eingefügt, damit Sie auch mit denselben Daten experimentieren können.
http://pastebin.com/ASnJ9M0p

Pieter-Jan Busschaert
quelle
1
Können Sie die Einschränkungen 1 und 5 etwas näher erläutern? Sie scheinen (auf den ersten Blick) widersprüchlich zu sein.
Peter K.
Ich verstehe wahrscheinlich falsch, was Sie mit "diesem Algorithmus" meinen, aber 5 Minuten für 5 MP scheinen eine Menge für die Anwendung eines Tiefpassfilters zu sein.
Björnz

Antworten:

8

Es gibt in der Tat eine 2D-Version für Ihren zweiten Versuch - sie ist theoretisch ähnlich, kann jedoch nicht in zwei 1D-Operationen zerlegt werden. Bitte lesen Sie über "2D-Graustufen-Filterung". Es ist schneller als die Kurvenanpassung.

Die Medianfilterung kann auch nützlich sein, wenn Sie versuchen, Flecken zu entfernen. Eine fortgeschrittenere Form der Medianfilterung ist die "Ordinalfilterung".

In allen Fällen kann die Anforderung Nr. 1 trivial erfüllt werden, indem das pixelweise Minimum zwischen der Ausgabe und der Eingabe genommen wird. Dies ist ein wichtiges Qualitätskriterium, schränkt jedoch die Auswahl der Algorithmen nicht ein.


Gaußsche Filterung (und eine Reihe anderer nützlicher Filter) können zerlegt werden (zuerst von 2D- zu 1D-Operationen, dann über Fourier-Transformation), aber es gibt viele andere nützliche Bildverarbeitungstechniken, die nicht zerlegbar sind, wodurch sie langsam werden, sich aber nicht verringern ihre Nützlichkeit.

rwong
quelle
Hallo, danke für den Hinweis auf die morphologische Graustufenfilterung. Die Beschreibung auf Wikipedia scheint interessant zu sein und ich werde das untersuchen. In Ihrem Link zur OpenCV-Dokumentation sehe ich jedoch nur normale morphologische Filter, keine Graustufenfilter. Ich werde diese Option auf jeden Fall aktivieren und Ihnen die Ergebnisse mitteilen. Vielen Dank.
Pieter-Jan Busschaert
6
Hilft rwongs Vorschlag der Medianfilterung überhaupt? Es könnte hilfreich sein, ein wenig mehr darüber zu erklären, was Sie erreichen möchten, indem Sie ein einfaches Beispiel für die Daten und ein "falsches" Beispiel für das, was Sie herausholen möchten, präsentieren.
Peter K.
Ich habe meine Frage mit Beispieldaten + Ergebnissen aus verschiedenen Vorschlägen aktualisiert. Ich hoffe, die Dinge sind jetzt klarer.
Pieter-Jan Busschaert
2

Ich schlage vor, einen glättenden Spline zu verwenden.

So können Sie dies mit Matlab mit der robusten Spline-Glättungsfunktion SMOOTHN aus Matlab File Exchange tun (die den vollständigen Quellcode enthält, sodass Sie ihn bei Bedarf an einer anderen Stelle erneut implementieren können). Beachten Sie, dass es auch mit n-dimensionalen Daten funktioniert:

%# - get inputlist from pastebin

%# - smoothen data. Lower factor means less smooth
smoothingFactor = 1000;
smoothData = smoothn(inputlist,smoothingFactor);

%# - shift down
smoothData = smoothData - max(inputlist-smoothData);

%# - show results
plot(inputlist,'b'),hold on,plot(smoothData,'r')

Bildbeschreibung hier eingeben

Jonas
quelle
Vielen Dank für Ihren Vorschlag, ich werde es untersuchen. Aus Ihrem Diagramm geht hervor, dass ich einen viel höheren Glättungsfaktor als in Ihrem Beispiel benötige. Die steile Kante um x = 700 wird nicht entfernt und ist deutlich sichtbar. Auch die anfängliche Erhebung in x = [0, 400] wird überhaupt nicht entfernt. Denken Sie nicht, dass dies das gleiche Problem wie alle anderen Ansätze (Tiefpassfilter + Abwärtsbewegung) haben wird? Sie können den globalen Versatz zwischen den beiden Diagrammen sehen, der sich wahrscheinlich sogar erhöhen wird, wenn ich einen höheren SmoothingFactor verwende.
Pieter-Jan Busschaert
@ Pieter-JanBusschaert: Oh, ich dachte, der erste Gipfel wäre irgendwie nützlich für dich. Wie auch immer, alle Tiefpassfilter + Abwärtsbewegungen werden Schwierigkeiten mit dem steilen Anstieg bei ~ 650 haben: Sie werden diesen Teil flacher machen, und daher muss die Kurve viel nach unten bewegt werden. Ein Medianfilter gefolgt von einem glättenden Spline hilft ein bisschen.
Jonas