Introdução
Matplotlib é uma popular biblioteca de visualização de dados em Python. Ela possui diversas funcionalidades integradas, incluindo a capacidade de simular deficiências na visão de cores. Este laboratório irá guiá-lo pelos passos de como usar Matplotlib para simular deficiências na visão de cores.
Dicas para a VM
Após a inicialização da VM, clique no canto superior esquerdo para mudar para a aba Notebook e acessar o Jupyter Notebook para praticar.
Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido às limitações do Jupyter Notebook.
Se você enfrentar problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão, e resolveremos o problema prontamente para você.
Importar as bibliotecas e módulos necessários
Primeiramente, precisamos importar as bibliotecas e módulos necessários, incluindo Matplotlib, NumPy e colorspacious. Também definimos as opções de filtro de cores que queremos simular.
import functools
from pathlib import Path
import colorspacious
import numpy as np
_BUTTON_NAME = "Filter"
_BUTTON_HELP = "Simulate color vision deficiencies"
_MENU_ENTRIES = {
"None": None,
"Greyscale": "greyscale",
"Deuteranopia": "deuteranomaly",
"Protanopia": "protanomaly",
"Tritanopia": "tritanomaly",
}
Definir a função de filtro de cores
Em seguida, definimos uma função que cria uma função de filtro de cores com base no nome do filtro de cores. Esta função usa o módulo colorspacious para converter a imagem de entrada para um espaço de cores diferente com base no nome do filtro de cores.
def _get_color_filter(name):
"""
Dado um nome de filtro de cores, cria uma função de filtro de cores.
Parâmetros
----------
name : str
O nome do filtro de cores, um dos seguintes:
- ``"none"``: ...
- ``"greyscale"``: Converte a entrada para luminosidade.
- ``"deuteranopia"``: Simula a forma mais comum de daltonismo vermelho-verde.
- ``"protanopia"``: Simula uma forma mais rara de daltonismo vermelho-verde.
- ``"tritanopia"``: Simula a rara forma de daltonismo azul-amarelo.
As conversões de cores usam `colorspacious`_.
Retorna
-------
callable
Uma função de filtro de cores que tem a forma:
def filter(input: np.ndarray[M, N, D])-> np.ndarray[M, N, D]
onde (M, N) são as dimensões da imagem, e D é a profundidade de cor (3 para
RGB, 4 para RGBA). Alpha é passado inalterado e, caso contrário,
ignorado.
"""
if name not in _MENU_ENTRIES:
raise ValueError(f"Unsupported filter name: {name!r}")
name = _MENU_ENTRIES[name]
if name is None:
return None
elif name == "greyscale":
rgb_to_jch = colorspacious.cspace_converter("sRGB1", "JCh")
jch_to_rgb = colorspacious.cspace_converter("JCh", "sRGB1")
def convert(im):
greyscale_JCh = rgb_to_jch(im)
greyscale_JCh[..., 1] = 0
im = jch_to_rgb(greyscale_JCh)
return im
else:
cvd_space = {"name": "sRGB1+CVD", "cvd_type": name, "severity": 100}
convert = colorspacious.cspace_converter(cvd_space, "sRGB1")
def filter_func(im, dpi):
alpha = None
if im.shape[-1] == 4:
im, alpha = im[..., :3], im[..., 3]
im = convert(im)
if alpha is not None:
im = np.dstack((im, alpha))
return np.clip(im, 0, 1), 0, 0
return filter_func
Definir a entrada do menu
Definimos uma função que define a entrada do menu com base no nome do filtro de cores selecionado. Esta função atualiza a função de filtro de cores com base na seleção.
def _set_menu_entry(tb, name):
tb.canvas.figure.set_agg_filter(_get_color_filter(name))
tb.canvas.draw_idle()
Configurar a barra de ferramentas
Em seguida, definimos uma função que configura a barra de ferramentas com base no tipo de backend usado. Esta função cria um botão que permite ao usuário selecionar o tipo de filtro de cores a ser simulado.
def setup(figure):
tb = figure.canvas.toolbar
if tb is None:
return
for cls in type(tb).__mro__:
pkg = cls.__module__.split(".")[0]
if pkg != "matplotlib":
break
if pkg == "gi":
_setup_gtk(tb)
elif pkg in ("PyQt5", "PySide2", "PyQt6", "PySide6"):
_setup_qt(tb)
elif pkg == "tkinter":
_setup_tk(tb)
elif pkg == "wx":
_setup_wx(tb)
else:
raise NotImplementedError("O backend atual não é suportado")
Criar imagens de exemplo
Criamos imagens de exemplo para demonstrar a função de filtro de cores. Importamos uma imagem de exemplo de Grace Hopper e a plotamos usando Matplotlib. Também criamos um gráfico de ondas senoidais.
if __name__ == '__main__':
import matplotlib.pyplot as plt
from matplotlib import cbook
plt.rcParams['figure.hooks'].append('mplcvd:setup')
fig, axd = plt.subplot_mosaic(
[
['viridis', 'turbo'],
['photo', 'lines']
]
)
delta = 0.025
x = y = np.arange(-3.0, 3.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
imv = axd['viridis'].imshow(
Z, interpolation='bilinear',
origin='lower', extent=[-3, 3, -3, 3],
vmax=abs(Z).max(), vmin=-abs(Z).max()
)
fig.colorbar(imv)
imt = axd['turbo'].imshow(
Z, interpolation='bilinear', cmap='turbo',
origin='lower', extent=[-3, 3, -3, 3],
vmax=abs(Z).max(), vmin=-abs(Z).max()
)
fig.colorbar(imt)
## A sample image
with cbook.get_sample_data('grace_hopper.jpg') as image_file:
photo = plt.imread(image_file)
axd['photo'].imshow(photo)
th = np.linspace(0, 2*np.pi, 1024)
for j in [1, 2, 4, 6]:
axd['lines'].plot(th, np.sin(th * j), label=f'$\\omega={j}$')
axd['lines'].legend(ncols=2, loc='upper right')
plt.show()
Resumo
Neste laboratório, aprendemos como simular deficiências na visão de cores usando Matplotlib. Usamos o módulo colorspacious para converter a imagem de entrada para um espaço de cores diferente com base no nome do filtro de cores selecionado. Também criamos imagens de exemplo para demonstrar a função de filtro de cores.