Anticrénelage d'image #

Les images sont représentées par des pixels discrets, soit sur l'écran, soit dans un fichier image. Lorsque les données qui composent l'image ont une résolution différente de leur représentation à l'écran, nous verrons des effets d'aliasing. Leur degré de perceptibilité dépend de la quantité de sous-échantillonnage effectuée dans le changement de résolution (le cas échéant).

Lors du sous-échantillonnage des données, le crénelage est réduit en lissant d'abord, puis en sous-échantillonnant les données lissées. Dans Matplotlib, nous pouvons effectuer ce lissage avant de mapper les données sur les couleurs, ou nous pouvons effectuer le lissage sur les données RVB (A) dans l'image finale. La différence entre ceux-ci est illustrée ci-dessous et contrôlée avec l' argument du mot-clé interpolation_stage .

L'interpolation d'image par défaut dans Matplotlib est "anticrénelée", et elle est appliquée aux données. Cela utilise une interpolation Hanning sur les données fournies par l'utilisateur pour réduire le crénelage dans la plupart des situations. Ce n'est que lorsqu'il y a suréchantillonnage par un facteur de 1, 2 ou >=3 que l'interpolation du voisin « le plus proche » est utilisée.

D'autres filtres d'anticrénelage peuvent être spécifiés à Axes.imshowl'aide de l' argument du mot clé d' interpolation .

import numpy as np
import matplotlib.pyplot as plt

Nous générons d'abord une image de 450 x 450 pixels avec un contenu fréquentiel variable :

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

Les images suivantes sont sous-échantillonnées de 450 pixels de données à 125 pixels ou 250 pixels (selon votre écran). Les modèles de moiré dans l'interpolation « la plus proche » sont causés par le sous-échantillonnage des données haute fréquence. L'image "anticrénelée" a encore quelques motifs moirés, mais ils sont considérablement réduits.

Il existe des différences substantielles entre l'interpolation 'données' et l'interpolation 'rgba'. Les bandes alternées de rouge et de bleu sur le tiers gauche de l'image sont sous-échantillonnées. En interpolant dans l'espace "données" (par défaut), le filtre anticrénelage rend les bandes proches du blanc, car la moyenne de -1 et +1 est nulle, et zéro est blanc dans cette palette de couleurs.

Inversement, lorsque l'anticrénelage se produit dans l'espace 'rgba', le rouge et le bleu sont combinés visuellement pour donner du violet. Ce comportement ressemble plus à un package de traitement d'image typique, mais notez que le violet n'est pas dans la palette de couleurs d'origine, il n'est donc plus possible d'inverser les pixels individuels à leur valeur de données.

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='plus proche' space='data', interpolation='antialiased' space='data', interpolation='antialiased' space='rgba'

Même le suréchantillonnage d'une image avec une interpolation "la plus proche" conduira à des motifs de moiré lorsque le facteur de suréchantillonnage n'est pas entier. L'image suivante suréchantillonne 500 pixels de données à 530 pixels rendus. Vous pouvez remarquer une grille de 30 artefacts en forme de ligne qui proviennent des 524 - 500 = 24 pixels supplémentaires qui ont dû être constitués. Étant donné que l'interpolation est "la plus proche", ils sont identiques à une ligne de pixels voisine et étirent ainsi l'image localement de sorte qu'elle semble déformée.

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()
suréchantillonné par le facteur a 1,048, interpolation='plus proche'

De meilleurs algorithmes d'anticrénelage peuvent réduire cet effet :

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()
suréchantillonné par le facteur a 1.048, interpolation='antialiased'

Outre l'anticrénelage "hanning" par défaut, prend en imshowcharge un certain nombre d'algorithmes d'interpolation différents, qui peuvent fonctionner mieux ou moins bien selon le modèle.

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'

Références

L'utilisation des fonctions, méthodes, classes et modules suivants est illustrée dans cet exemple :

Durée totale d'exécution du script : (0 minutes 3,316 secondes)

Galerie générée par Sphinx-Gallery