Bild-Antialiasing #

Bilder werden entweder auf dem Bildschirm oder in einer Bilddatei durch diskrete Pixel dargestellt. Wenn Daten, aus denen das Bild besteht, eine andere Auflösung haben als die Darstellung auf dem Bildschirm, treten Aliasing-Effekte auf. Wie auffällig diese sind, hängt davon ab, wie viel Downsampling bei der Auflösungsänderung (falls vorhanden) stattfindet.

Beim Unterabtasten von Daten wird Aliasing reduziert, indem zuerst geglättet und dann die geglätteten Daten unterabgetastet werden. In Matplotlib können wir diese Glättung durchführen, bevor wir die Daten Farben zuordnen, oder wir können die RGB(A)-Daten im endgültigen Bild glätten. Der Unterschied zwischen diesen wird unten gezeigt und mit dem Schlüsselwortargument interpolation_stage gesteuert.

Die standardmäßige Bildinterpolation in Matplotlib ist „antialiased“ und wird auf die Daten angewendet. Dies verwendet eine Hanning-Interpolation für die vom Benutzer bereitgestellten Daten, um in den meisten Situationen Aliasing zu reduzieren. Nur bei einem Upsampling um den Faktor 1, 2 oder >=3 wird die Nearest-Neighbor-Interpolation verwendet.

Andere Anti-Aliasing-Filter können Axes.imshowmit dem Schlüsselwortargument Interpolation angegeben werden.

import numpy as np
import matplotlib.pyplot as plt

Zuerst erzeugen wir ein 450x450-Pixel-Bild mit variierendem Frequenzinhalt:

N = 450
x = np.arange(N) / N - 0.5
y = np.arange(N) / N - 0.5
aa = np.ones((N, N))
aa[::2, :] = -1

X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
f0 = 5
k = 100
a = np.sin(np.pi * 2 * (f0 * R + k * R**2 / 2))
# make the left hand side of this
a[:int(N / 2), :][R[:int(N / 2), :] < 0.4] = -1
a[:int(N / 2), :][R[:int(N / 2), :] < 0.3] = 1
aa[:, int(N / 3):] = a[:, int(N / 3):]
a = aa

Die folgenden Bilder werden von 450 Datenpixeln auf 125 Pixel oder 250 Pixel (je nach Anzeige) subsampled. Die Moiré-Muster in der „nächsten“ Interpolation werden durch die Unterabtastung der hochfrequenten Daten verursacht. Das „Antialiased“-Bild weist auch noch einige Moiré-Muster auf, aber sie sind stark reduziert.

Es gibt wesentliche Unterschiede zwischen der „Daten“-Interpolation und der „rgba“-Interpolation. Die abwechselnden roten und blauen Bänder im linken Drittel des Bildes werden unterabgetastet. Durch Interpolation im 'Daten'-Raum (Standardeinstellung) macht der Antialiasing-Filter die Streifen fast weiß, da der Durchschnitt von -1 und +1 null ist und null in dieser Farbkarte weiß ist.

Umgekehrt, wenn das Anti-Aliasing im 'rgba'-Raum auftritt, werden Rot und Blau visuell kombiniert, um Violett zu erzeugen. Dieses Verhalten ähnelt eher einem typischen Bildverarbeitungspaket, aber beachten Sie, dass Violett nicht in der ursprünglichen Farbtabelle enthalten ist, sodass es nicht mehr möglich ist, einzelne Pixel auf ihren Datenwert zurückzusetzen.

fig, axs = plt.subplots(2, 2, figsize=(5, 6), constrained_layout=True)
axs[0, 0].imshow(a, interpolation='nearest', cmap='RdBu_r')
axs[0, 0].set_xlim(100, 200)
axs[0, 0].set_ylim(275, 175)
axs[0, 0].set_title('Zoom')

for ax, interp, space in zip(axs.flat[1:],
                             ['nearest', 'antialiased', 'antialiased'],
                             ['data', 'data', 'rgba']):
    ax.imshow(a, interpolation=interp, interpolation_stage=space,
              cmap='RdBu_r')
    ax.set_title(f"interpolation='{interp}'\nspace='{space}'")
plt.show()
Zoom, interpolation='nächste' space='data', interpolation='antialiased' space='data', interpolation='antialiased' space='rgba'

Selbst das Upsampling eines Bildes mit der „nächstgelegenen“ Interpolation führt zu Moiré-Mustern, wenn der Upsampling-Faktor nicht ganzzahlig ist. Im folgenden Bild werden 500 Datenpixel auf 530 gerenderte Pixel hochgerechnet. Sie können ein Raster aus 30 linienartigen Artefakten bemerken, die von den 524 - 500 = 24 zusätzlichen Pixeln stammen, die erstellt werden mussten. Da die Interpolation „am nächsten“ ist, sind sie gleich wie eine benachbarte Pixelzeile und dehnen somit das Bild lokal, so dass es verzerrt aussieht.

fig, ax = plt.subplots(figsize=(6.8, 6.8))
ax.imshow(a, interpolation='nearest', cmap='gray')
ax.set_title("upsampled by factor a 1.048, interpolation='nearest'")
plt.show()
upsampled um Faktor a 1.048, interpolation='nearest'

Bessere Antialiasing-Algorithmen können diesen Effekt reduzieren:

fig, ax = plt.subplots(figsize=(6.8, 6.8))
ax.imshow(a, interpolation='antialiased', cmap='gray')
ax.set_title("upsampled by factor a 1.048, interpolation='antialiased'")
plt.show()
upsampled um Faktor a 1.048, interpolation='antialiased'

Unterstützt neben dem standardmäßigen „Hanning“-Antialiasing imshoweine Reihe verschiedener Interpolationsalgorithmen, die je nach Muster besser oder schlechter funktionieren können.

fig, axs = plt.subplots(1, 2, figsize=(7, 4), constrained_layout=True)
for ax, interp in zip(axs, ['hanning', 'lanczos']):
    ax.imshow(a, interpolation=interp, cmap='gray')
    ax.set_title(f"interpolation='{interp}'")
plt.show()
interpolation='hanning', interpolation='lanczos'

Verweise

In diesem Beispiel wird die Verwendung der folgenden Funktionen, Methoden, Klassen und Module gezeigt:

Gesamtlaufzeit des Skripts: ( 0 Minuten 3.316 Sekunden)

Galerie generiert von Sphinx-Gallery