5.13. Lineare Filter und Nachbarschaftsfilter¶
Die Pixelmathematik-Operationen weiter oben im Kapitel kombinierten zwei Bilder Punkt für Punkt. Filter leisten verwandte Arbeit auf andere Weise: Sie berechnen den Wert jedes Ausgabepixels aus einer kleinen Nachbarschaft von Eingabepixeln rund um die entsprechende Position. Die Ausgabe an (x, y) ist eine Statistik – der Durchschnitt, der Median, der häufigste Wert – der Eingabepixel in einem kleinen Kasten, der auf (x, y) zentriert ist.
Diese kleine Verschiebung der Sichtweise – vom einzelnen Pixel hin zu einem ganzen Pixelfenster – ist es, die eine ganze Familie nützlicher Operationen ermöglicht. Ein einfacher Durchschnitt über ein kleines Fenster glättet Sensorrauschen heraus. Der Median über dasselbe Fenster entfernt einzelne Sprenkel, ohne Kanten so stark weichzuzeichnen. Ein bilateraler Durchschnitt verweigert die Glättung über starke Kontrastgrenzen hinweg und bewahrt so die Kanten von Objekten, während er die Texturen in ihrem Inneren bereinigt. Die Nachbarschaft ist die Arbeitseinheit; die Wahl der Statistik entscheidet, was der Filter tut.
5.13.1. Die Kernelgröße¶
Jeder Nachbarschaftsfilter nimmt einen size-Parameter, der den Radius des Fensters in Pixeln festlegt. Das Fenster selbst ist quadratisch und deckt (2 * size + 1) Pixel pro Seite ab – size=1 bedeutet also eine 3-mal-3-Nachbarschaft, size=2 bedeutet 5-mal-5, size=3 bedeutet 7-mal-7 und so weiter.
Die Nachbarschaft gleitet pixelweise über das Bild, von oben links nach unten rechts. Jedes Ausgabepixel ist das Ergebnis der Anwendung der Filterstatistik auf die darauf zentrierte Eingabenachbarschaft.¶
Größere Werte bedeuten größere Nachbarschaften, was eine glattere (oder aggressivere) Filterung bedeutet. Der Aufwand wächst mit der Fläche des Fensters, sodass ein size=3-Filter pro Pixel etwa neunmal so viel Arbeit leistet wie ein size=1-Filter. Der praktische Standard für die meisten Bereinigungsaufgaben ist size=1 oder size=2; greifen Sie nur dann zu größeren Werten, wenn kleine Nachbarschaften nicht ausreichen, um das Merkmal zu unterdrücken, das die Anwendung unterdrücken will.
5.13.2. Der Mittelwertfilter¶
mean() ersetzt jedes Pixel durch den arithmetischen Durchschnitt seiner Nachbarschaft. Das Ergebnis glättet Pixel-zu-Pixel-Variationen über die Größe des Fensters, was es zur günstigsten Methode macht, um Sensorrausch-Sprenkel zu unterdrücken: Hochfrequente Variation mittelt sich heraus, niederfrequenter Inhalt bleibt erhalten.
Der Nachteil ist, dass auch Kanten und andere scharfe Merkmale gemittelt werden. Eine helle Kante, die vor dem Filter ein Pixel breit war, ist nach einem size=1-Mittelwertfilter zwei oder drei Pixel breit, wobei die Helligkeit an den Flanken abfällt. Für reine Rauschreduktion auf einem texturarmen Bild (eine saubere Wand, das Innere eines farbigen Markers) ist der Kompromiss in Ordnung. Für eine unruhige Szene, in der Kanten wichtig sind, eignet sich meist einer der folgenden Filter besser.
img.mean(1) # 3x3 box average -- fast, gentle smoothing
img.mean(2) # 5x5 box average -- stronger, slower
5.13.3. Median, Modus, Mittelpunkt¶
Die drei anderen statistischen Nachbarschaftsfilter tauschen den einfachen arithmetischen Durchschnitt gegen etwas, das robuster gegenüber Ausreißern ist.
median() gibt den Median der Nachbarschaft zurück – den Wert, der in der Mitte der sortierten Liste der Fensterpixel landet. Ein einzelnes sehr helles oder sehr dunkles Pixel im Fenster zieht den Median nicht; es wird einfach zu einem der verworfenen Extremwerte. Der praktische Effekt ist, dass die Medianfilterung einzelne Sprenkel und Salz-und-Pfeffer-Rauschen entfernt, ohne Kanten so weichzuzeichnen wie mean. Der Preis ist mehr Rechenaufwand pro Pixel – das Sortieren eines Fensters ist langsamer als das Mitteln – und das Ergebnis ist nicht streng genommen ein Durchschnitt, was für nachgelagerte Berechnungen mitunter eine Rolle spielt.
Ein percentile-Parameter (Standard 0.5) verschiebt den gewählten Wert weg vom strikten Median. percentile=0.0 gibt das Minimum der Nachbarschaft zurück, percentile=1.0 das Maximum; Zwischenwerte wählen proportional zwischen ihnen im sortierten Fenster. Das gibt median die Fähigkeit, dunkle oder helle Teile der Nachbarschaft hervorzuheben, ohne die Ausreißerrobustheit der Ordnungsstatistik zu verlieren.
mode() gibt den häufigsten Wert in der Nachbarschaft zurück. Nützlich, wenn das Rauschmodell lautet „die meisten Pixel sind korrekt, einige wurden in unterschiedlichem Maße verfälscht“, wobei die richtige Antwort derjenige Wert ist, der am häufigsten vorkommt – was der Median verfehlen kann, wenn sich die verfälschten Werte auf einer Seite des sortierten Fensters häufen.
midpoint() gibt eine gewichtete Kombination aus dem Minimum und dem Maximum der Nachbarschaft zurück – bias=0.5 ergibt den Mittelpunkt zwischen ihnen, bias=0.0 ergibt das Minimum, bias=1.0 ergibt das Maximum. Weniger häufig verwendet als die anderen, aber gut zu kennen, wenn das Ziel speziell darin besteht, dunkle oder helle Merkmale zu extrahieren.
5.13.4. Bilateral, die kantenerhaltende Variante¶
bilateral() ist der Nachbarschaftsfilter, dessen gutes Verständnis sich am meisten lohnt. Er erzeugt den Glättungseffekt von mean(), jedoch mit einer zusätzlichen Einschränkung: Je stärker sich ein Nachbarschaftspixel vom Zentrumspixel unterscheidet, desto weniger zählt es im Durchschnitt. Das Ergebnis glättet das Innere jeder gleichmäßigen Region, ohne über die Kanten zu verlaufen, die sie trennen – genau das, was die meisten Anwendungen tatsächlich wollen.
Zwei Parameter steuern, wie aggressiv der Filter Pixel abwertet:
color_sigmaentscheidet, wie der Farbunterschied die Gewichtung beeinflusst. Kleinere Werte bedeuten, dass der Filter strenger Pixel abwertet, die sich vom Zentrum unterscheiden.space_sigmaentscheidet, wie der räumliche Abstand die Gewichtung beeinflusst. Kleinere Werte geben Pixeln nahe dem Zentrum mehr Gewicht.
Die Standardwerte (color_sigma=0.1, space_sigma=1.0) sind vernünftige Ausgangspunkte; ihre Abstimmung ist meist eine Frage des Ausführens des Filters auf einem Beispiel-Einzelbild und des Anpassens, bis die Kanten scharf und die Innenbereiche sauber sind.
Bilateral ist teurer als median() und deutlich teurer als mean(), daher lohnt es sich, nur dann darauf zurückzugreifen, wenn das kantenerhaltende Verhalten genau das ist, was die Anwendung benötigt.
5.13.5. Adaptive Schwellenwertbildung¶
Die Filter Mittelwert, Median, Modus und Mittelpunkt tragen alle dasselbe Paar von Schlüsselwortargumenten, die ihre Ausgabe in einen binären Schwellenwert verwandeln:
threshold=Trueschaltet den Filter in den Schwellenwertmodus.offset=Nverschiebt die lokale Trennschwelle vor dem Vergleich umNEinheiten.
Der Mechanismus baut direkt auf dem gewöhnlichen Verhalten des Filters auf. Ohne threshold=True berechnet der Filter seine Statistik über die Nachbarschaft und schreibt diese Statistik in das Ausgabepixel. Mit threshold=True berechnet der Filter dieselbe Statistik, vergleicht dann das Quellpixel an derselben Position mit der Statistik plus dem Offset und schreibt den Maximalwert des Formats, wenn die Quelle größer ist, andernfalls null.
Das Ergebnis ist ein Binärbild, dessen Trennschwelle sich mit der lokalen Helligkeit über das Einzelbild hinweg bewegt. Helle Regionen erhalten eine hohe Trennschwelle, dunkle Regionen eine niedrige, und ein Vordergrundpixel, das lokal heller ist als seine Nachbarn, wird erkannt, egal ob es in einer hellen oder einer dunklen Region liegt – genau das Verhalten, das ein einzelner globaler Schwellenwert bei einem ungleichmäßig beleuchteten Bild nicht erzeugen könnte.
img.mean(3, threshold=True, offset=5)
Der offset-Parameter ist der Ort, an dem die Anwendung steuert, wie streng der Test ist. Ein kleiner positiver Offset verlangt, dass das Quellpixel messbar heller ist als seine Nachbarn, bevor es als Treffer zählt, was Sensorrausch-Fehltreffer unterdrückt, auf Kosten des Verlusts schwachen Vordergrunds. Ein kleiner negativer Offset erfasst schwachen Vordergrund, lässt dafür aber etwas Rauschen durch. Die Wahl hängt davon ab, was der Rest der Pipeline mit der binären Ausgabe machen wird.
Bei ungleichmäßiger Beleuchtung kann ein einzelner globaler Schwellenwert den Vordergrund nicht an jeder Position beschreiben. Ein mit threshold=True ausgeführter Nachbarschaftsfilter erzeugt eine Trennschwelle, die sich mit der lokalen Helligkeit bewegt, und klassifiziert den Vordergrund über das gesamte Einzelbild hinweg korrekt.¶
Die Filterfamilie führt den adaptiven Schwellenwert aus, daher ist die Wahl des richtigen Filters wichtig: mean() für den günstigsten adaptiven Schwellenwert, median(), wenn die Eingabe Salz-und-Pfeffer-Rauschen enthält, das der Filter vor der Berechnung der lokalen Trennschwelle verwerfen soll.