5.15. Morphologische Operationen

Morphologische Operationen arbeiten mit Binärbildern – den Masken, die aus Schwellenwertbildung und Kantenerkennung hervorgehen. Jede Operation durchläuft dieselbe Art gleitender Nachbarschaft, die auch die Glättungsfilter verwenden, doch die Frage, die sie an jeder Position stellt, ist ja/nein: Ist jedes Pixel in der Nachbarschaft an, ist irgendein Pixel in der Nachbarschaft an, wie sieht das An/Aus-Muster aus? Die Antworten lassen Regionen wachsen, schrumpfen sie und schneiden ihre Grenzen auf eine Weise neu, die ein mittelnder Filter nicht kann.

Morphologie ist das, was zwischen einer anfänglichen Binärmaske – der Ausgabe von Schwellenwertbildung, Kantenerkennung oder einem anderen Klassifikator – und der sauberen Binärmaske steht, die der Rest der Pipeline verwenden kann. Eine rohe Schwellenwertausgabe weist meist vereinzelte Rauschpixel auf, die über echte Vordergrundbereiche verstreut sind, kleine Löcher in ansonsten massiven Regionen sowie gezackte Grenzen dort, wo der Schwellenwert nah an der Objektkante geschnitten hat. Morphologie entfernt diese Defekte.

5.15.1. Die vier klassischen Operationen

Zwei elementare Operationen und zwei Zusammensetzungen daraus bilden das morphologische Werkzeugset:

dilate() vergrößert jede Vordergrundregion. Die Regel lautet: Jedes Pixel, das mindestens einen Vordergrundnachbarn in seinem (2 * size + 1)-Fenster hat, wird zu Vordergrund. Der sichtbare Effekt ist, dass Vordergrundregionen in jeder Richtung um size Pixel größer werden und Löcher in ihrem Inneren um denselben Betrag schrumpfen (oder verschwinden).

erode() macht das Umgekehrte. Jedes Pixel, das nicht jeden Nachbarn in seinem Fenster im Vordergrund hat, wird zu Hintergrund. Vordergrundregionen werden in jeder Richtung um size Pixel kleiner, vereinzelte Vordergrundpixel (die keine Vordergrundnachbarn haben) verschwinden vollständig, und kleine Verbindungen zwischen größeren Regionen werden durchtrennt.

Eine binäre Eingaberegion in der ganz linken Tafel: ein massives Quadrat mit einem Ein-Pixel- Loch in seiner Mitte und drei vereinzelten Rauschpixeln darum herum. Vier Tafeln rechts zeigen das Ergebnis der Anwendung von dilate, erode, open und close auf diese Eingabe. Dilate vergrößert die Region, füllt das Loch und vergrößert jedes Rauschpixel zu einem Block; erode verkleinert die Region, vergrößert das Loch und entfernt das Rauschen; open entfernt das Rauschen, während es die Region und ihr Loch exakt reproduziert; close füllt das Loch, während es den Umriss der Region und die Rauschpixel exakt reproduziert.

Die vier klassischen morphologischen Operationen, angewandt auf eine verrauschte Binärregion. Erode verkleinert; dilate vergrößert; open ist erode gefolgt von dilate (entfernt Rauschen); close ist dilate gefolgt von erode (füllt Löcher).

open() ist erode gefolgt von dilate. Aus dem erodierten Bild wurde jedes vereinzelte Rauschpixel entfernt, aber es wurde auch in jeder Richtung um size Pixel geschrumpft. Wenn dem erode ein dilate derselben Größe folgt, werden die echten Vordergrundregionen ungefähr auf ihre ursprünglichen Grenzen zurückgeführt, während das Rauschen verschwunden bleibt. Diese Zusammensetzung macht open zur Standardoperation zum „Entfernen von Rauschen“ in der klassischen Morphologie: Vereinzelte Vordergrundpixel verschwinden, echte Regionen kehren unbeschadet zurück.

close() ist das Spiegelbild – dilate gefolgt von erode. Das dilate füllt kleine Löcher in Vordergrundregionen und verbindet Regionen, die durch kleine Lücken getrennt sind; das erode schrumpft das Ergebnis auf seine ursprüngliche äußere Grenze zurück, während das aufgefüllte Innere massiv bleibt. close ist die Standardoperation zum „Füllen kleiner Lücken“.

binary_mask.open(1)       # remove single-pixel noise
binary_mask.close(2)      # fill small holes and gaps

Der Größenparameter hat dieselbe Bedeutung wie bei den Helligkeitsfiltern: size=1 bedeutet eine 3-mal-3-Nachbarschaft, size=2 bedeutet 5-mal-5 und so weiter. Größere Werte bedeuten aggressivere Bereinigung – und einen höheren Aufwand pro Pixel.

5.15.2. Top-Hat und Black-Hat

Zwei weitere Zusammensetzungen sind wissenswert, weil sie genau die Merkmale extrahieren, die open und close entfernen:

top_hat() gibt die Differenz zwischen dem Originalbild und seiner geöffneten Version zurück – die Vordergrundpixel, die open entfernt hätte. Das ist buchstäblich eine Maske der Rauschpixel, der vereinzelten kleinen Vordergrundregionen, der dünnen Vordergrundstrukturen, die die Open-Operation nicht erhalten konnte. Nützlich zum Extrahieren kleiner Vordergrundmerkmale, wenn diese Merkmale genau das sind, worauf es der Anwendung ankommt, statt sie zu entfernen.

black_hat() gibt die Differenz zwischen der geschlossenen Version des Bildes und dem Original zurück – die Hintergrundpixel, die close aufgefüllt hätte. Das ist eine Maske der kleinen Löcher in Vordergrundregionen, der schmalen Lücken zwischen Regionen, die die Close-Operation überbrückt hätte.

Beide werden seltener verwendet als die vier Grundoperationen, aber das Muster ist es wert, sich zu merken – wenn eine Anwendung kleine oder dünne Merkmale extrahieren muss, die der Standard-Bereinigungsdurchlauf entfernt, sind Top-Hat und Black-Hat der natürliche Weg, sie zurückzugewinnen.

5.15.3. Schwellenwertmodus

Die vier morphologischen Grundoperationen akzeptieren alle ein ganzzahliges threshold-Schlüsselwort, das den An/Aus-Test an jeder Position aufweicht. Ohne es verhalten sich die Operationen so, wie es die obigen Beschreibungen besagten: erode() verlangt, dass jeder Nachbar an ist, dilate() verlangt mindestens einen. Mit gesetztem threshold toleriert jede Operation, dass so viele Nachbarn anders stimmen. Bei erode ist threshold die Anzahl der Hintergrund-Nachbarn, die ein Pixel haben darf und dennoch überlebt: threshold=4 behält jedes Pixel, bei dem mindestens vier seiner acht Nachbarn an sind (in einem 3-mal-3-Fenster hat das Zentrumspixel acht Nachbarn), sodass es nicht so aggressiv erodiert. Bei dilate ist threshold die Anzahl der Vordergrund-Nachbarn, von denen ein Hintergrundpixel mehr haben muss, bevor es angeht: threshold=2 verlangt mindestens drei Vordergrundnachbarn statt einem, sodass es weniger aggressiv wächst.

Die Schwellenwertform ist nützlich, um die Aggressivität eines morphologischen Durchlaufs abzustimmen, ohne die Größe seines Fensters zu ändern, was auch den Maßstab der Merkmale ändern würde, auf die er wirkt. Die meisten Anwendungen bleiben beim Standardverhalten; die Schwellenwertform ist für die Fälle da, in denen der Standard nur geringfügig zu viel oder zu wenig ist.