Filter-o-rama

siehe auch: http://de.wikipedia.org/wiki/Digitale_Bildverarbeitung
Farbcodierung:
Glättung
Kantendetektion
Eckendetektion
Segmentierung

Box-Filter (Mittelwert-Filter)

einfacher 3x3 Filter, linear
Zweck: Glätten des Signals, Rauschunterdrückung
Konstruktion:
Nachteil: dämpft an einigen Stellen gar nicht! (s.Spektrum, FT des Filters ist die sinc-Funktion)
1 1 1
1 1 1
1 1 1

Normierung durch Multiplikation mit 1/9

Gauss Filter*,**

linear
Zweck: Glätten des Signals, Rauschunterdrückung
Konstruktion: mit der Funktion g(x,σ) = exp^-(x^2/2σ^2)
besser: filtert die hohen Frequenz komplett heraus
1 2 1
2 4 2
1 2 1

Binomial Filter

linear
Zweck: Glätten des Signals
Konstruktion: "Binomialgenerator"
1 2 1
2 4 2
1 2 1

Median Filter

Zweck: Glätten des Signals, insbesondere Beseitigen von Impulsrauschen (Salt & Pepper)
Maske (Strukturierendes Element) beliebig
Vorteil: Kontraste bleiben (besser) erhalten, Impulsrauschen
Algorithmus: Sortieren der Eingangswerte, Ersetzen nach Vorschrift: Median (auch: min, max)
Unterschied zu lin. Filtern: keine Modellierung durch Faltung möglich

Differentialmaske

Zweck: Kontrastdetektion (durch Hervorheben von Kontrasten)
Konstruktion:
Nachteil: störungsanfällig (s. durch differenzieren verstärktes additives Rauschen)

Vorwärts-/Rückwärts-Differenz:
-1 1

Zentraldifferenz (Vorteil: geringeres Restglied d. Taylorreihe):
-1 0 1

2. Ableitung:
1 -2 1
des weiteren gibt es noch fest orientierte Kantendetektoren, wie z.B. den Kirsch-Operator (8 mal 3x3) oder Nevatia Babu (6 mal 5x5) die die maximale Antwort der einzelnen Richtungsmasken zurückgeben.

Funktion: max arg(max[K0(),..., K7()])

Roberts Kreuz Operator

Konstruktion: Ausschnitt aus einer geglätteten Vorwärtsdifferenzenmaske
Funktion: Gradienten über Kreuz berechnen und Maximum wählen

0 0 0
-1 -1 -1
1 1 1

Prewitt

Zweck: Kontrastdetektion
Konstruktion: 1. Ableitung, gewichtete Differentialmaske
besser: Rauschunterdrückung
-1 0 1
-1 0 1
-1 0 1

Sobel

Zweck: Kontrastdetektion, Detektieren von 1-dimensionalen Grauwertstrukturen
Konstruktion: 1. Ableitung, distanzabhängige Binomialgewichtung orthogonal zur Kontrastrichtung(?)
besser: ???
-1 0 1
-2 1 2
-1 1 1

Laplace

Zweck: Kontrastdetektion
Konstruktion: fxx + fyy
0 1 0
1 -4 1
0 1 0

Bemerkung: 2. Ableitung noch störungsanfälliger, deshalb
(a) Laplace mit Binomialmaske (distanzabhängige Gewichtung) orthogonal zum Kontrast
1 -2 1
2 -4 2
1 -2 1
+
1 2 1
-2 -4 -2
1 2 1
=
2 0 2
0 -8 0
2 0 2

 (2) Kombination mit Gauss-Glättungsmaske → LoG (Laplacian of Gaussian)

Canny

Zweck: 1-dim. Kontrastdetektion
besser: 1 Pixel breite Linien (gut für Konturbeschreibung), nur markante Kontraste
Algorithmus: Sobel-Operator, Nonmax. Suppression, Hysteresis Thresholding
Nachteil: hoher Berechnungsaufwand
zur Liniendetektion: Linien können im Graustufen-Höhenbild als lokale Maxima bzw. Minima betrachtet werden.
Lokales Max. → Nulldurchg. in 1. Ableitung → < 0 in 2. Ableitung
Lokales Min. → Nulldurchg. in 1. Ableitung → > 0 in 2. Ableitung
Deshalb die 2. Ableitung (Min. = dunkle Linie, Max. = helle Linie).
-1,2-1 für dunkle Linien, 1,-2,1 für helle Linien

Maskengröße ist abhängig von d. Linienbreite. 1 Pixel breite Linien → 3x3 Maske

Moravec

Bemerkung: helleres/dunkleres Bild beeinflusst den Schwellwert!

Strukturtensor

Bemerkung: helleres/dunkleres Bild beeinflusst die Eigenwerte, hat allerdings nur einen Einfluß, wenn λ2 alleine betrachtet wird.

Hough

globale Operation, Votierungsverfahren
kann als Pattern Matching angesehen werden
Vorteile: Kann gut mit Verdeckungen umgehen, robustes Verhalten gegenüber Rauschen

Interessant beim Filtern ist die Randbehandlung, hier gibt es u.a. Neumann (Kopie) und Dirichlet (Null setzen) oder auch spiegeln. - richtig so?



* separierbare Filterkernel, wie z.B. der Gauss Kernel haben den Vorteil, dass eine 2D-Faltung zwei 1D Faltungen über alle Zeilen und über alle Reihen entspricht.
   Die Zeitkomplexität wächst also linear mit der Maskengröße und nicht quadratisch.
** Python Skript, das 1D Gauss Kernel für Sigma zwischen 0.5 und 1.0 berechnet und diese auf Integer Werte skaliert

import math

size = 5

for sigma in range(50,100+1,5):
    sigma = float(sigma) / 100

    y0 = math.exp(-pow(-(size/2),2)/(2*pow(sigma,2)))
    print "sigma = %f:" % sigma
    for x in range(-(size/2),size/2+1):
        y = math.exp(-pow(x,2)/(2*pow(sigma,2)))
        print "integer kernel: %f" % round((y*(1/y0)))
    print ""

Ausgabe:
sigma = 0.500000:
integer kernel: 1.000000
integer kernel: 403.000000
integer kernel: 2981.000000
integer kernel: 403.000000
integer kernel: 1.000000

[...]

sigma = 0.850000:
integer kernel: 1.000000
integer kernel: 8.000000
integer kernel: 16.000000
integer kernel: 8.000000
integer kernel: 1.000000

[...]

sigma = 0.950000:
integer kernel: 1.000000
integer kernel: 5.000000
integer kernel: 9.000000
integer kernel: 5.000000
integer kernel: 1.000000

sigma = 1.000000:
integer kernel: 1.000000
integer kernel: 4.000000
integer kernel: 7.000000
integer kernel: 4.000000
integer kernel: 1.000000