Observação
Clique aqui para baixar o código de exemplo completo
Antialiasing de imagem #
As imagens são representadas por pixels discretos, na tela ou em um arquivo de imagem. Quando os dados que compõem a imagem tiverem uma resolução diferente de sua representação na tela, veremos efeitos de aliasing. O quão perceptíveis eles são depende de quanto downsampling ocorre na mudança de resolução (se houver).
Ao subamostrar dados, o aliasing é reduzido suavizando primeiro e depois subamostrando os dados suavizados. No Matplotlib, podemos fazer essa suavização antes de mapear os dados para as cores, ou podemos fazer a suavização nos dados RGB(A) na imagem final. A diferença entre eles é mostrada abaixo e controlada com o argumento de palavra-chave interpolation_stage .
A interpolação de imagem padrão no Matplotlib é 'antialiased' e é aplicada aos dados. Isso usa uma interpolação hanning nos dados fornecidos pelo usuário para aliasing reduzido na maioria das situações. Somente quando há upsampling por um fator de 1, 2 ou >=3 é usada a interpolação do vizinho 'mais próximo'.
Outros filtros anti-aliasing podem ser especificados Axes.imshow
usando o
argumento de palavra-chave de interpolação .
import numpy as np
import matplotlib.pyplot as plt
Primeiro, geramos uma imagem de 450x450 pixels com conteúdo de frequência variável:
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
As seguintes imagens são subamostradas de 450 pixels de dados para 125 pixels ou 250 pixels (dependendo do seu monitor). Os padrões Moire na interpolação 'mais próxima' são causados pelos dados de alta frequência sendo subamostrados. A imagem 'antialiased' ainda tem alguns padrões Moire também, mas eles são bastante reduzidos.
Existem diferenças substanciais entre a interpolação 'dados' e a interpolação 'rgba'. As bandas alternadas de vermelho e azul no terço esquerdo da imagem são subamostradas. Ao interpolar no espaço de 'dados' (o padrão) o filtro antialiasing torna as listras próximas do branco, porque a média de -1 e +1 é zero, e zero é branco neste mapa de cores.
Por outro lado, quando o anti-aliasing ocorre no espaço 'rgba', o vermelho e o azul são combinados visualmente para formar o roxo. Esse comportamento é mais parecido com um pacote de processamento de imagem típico, mas observe que o roxo não está no mapa de cores original, portanto, não é mais possível inverter pixels individuais de volta ao seu valor de dados.
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()
Mesmo o upsampling de uma imagem com a interpolação 'mais próxima' levará a padrões Moire quando o fator de upsampling não for inteiro. A imagem a seguir aumenta a resolução de 500 pixels de dados para 530 pixels renderizados. Você pode observar uma grade de 30 artefatos semelhantes a linhas que se originam dos 524 - 500 = 24 pixels extras que tiveram que ser compostos. Como a interpolação é 'mais próxima', eles são iguais a uma linha vizinha de pixels e, portanto, estica a imagem localmente para que pareça distorcida.
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()
Melhores algoritmos de suavização podem reduzir esse efeito:
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()
Além do antialiasing 'hanning' padrão, imshow
suporta vários algoritmos de interpolação diferentes, que podem funcionar melhor ou pior, dependendo do padrão.
Referências
O uso das seguintes funções, métodos, classes e módulos é mostrado neste exemplo:
Tempo total de execução do script: (0 minutos 3,316 segundos)