Fundamentos de Computação Gráfica - INF2608 - 2013.1
Trabalho 0 - Cor
O objetivo deste trabalho era apresentar em um monitor sRGB uma imagem do MacBeth ColorChecker da maneira mais precisa possível.
Para isso foi disponibilizado um arquivo no formato Excel com o espectro de radiância de cada unidade de cor (referenciada no trabalho como "patch") do Color Checker. Em cada espectro, as amostras variavam de 380nm a 780nm de comprimento de onda e o intervalo de amostragem era de 5nm.
Também foram fornecidas neste arquivo, as coordenadas das cores espectrais na base CIE XYZ, x_bar, y_bar, z_bar e as curvas das componentes espectrais dos iluminantes padrão D65 e A. Ambas informações são necessárias para se chegar à cor sRGB de cada patch.
Cálculos
Para calcular as cores sRBG de cada patch precisamos descobrir os valores das componentes X, Y e Z de cada um, para então convertê-las em sRGB.
Dado que temos: Os espectros de radiância dos patches, a distribuição espectral do iluminante de referência e as componentes espectrais na base CIE XYZ, podemos calcular para cada patch as componentes X, Y e Z:
(Fórmulas para o caso Reflexivo, onde o objeto(patch) sendo observado não emite luz, mas é iluminado pelo iluminante de referencia)
Onde, x_bar(), y_bar(), z_bar(), S e I são as curvas espectrais: Dos componentes na base CIE XYZ, das cores e do Iluminante, respectivamente. E dT, é o intervalo de amostragem da curva, no caso 5nm.
As integrais acima são substituídas por somatórios, pois na prática as funções nela existentes se traduzem em medidas e experimentos empíricos, não existindo funções matemáticas que as representam.
Temos então que as fórmulas tornam-se:
Sendo que no caso deste trabalho temos a constante dT na multiplicação fora do somatório.
Implementação
O módulo
color.c fornecido continha as funções necessárias para os cálculos explicitados acima. E como neste também já havia estruturas com os valores das componentes x_bar(), y_bar(), z_bar() (para o observador padrão de grau 2, pois para o trabalho corrente o objetivo de visualização é para distâncias curtas) e dos espectros dos iluminantes, não foi necessário o carregamento(load) destes valores para a aplicação. Já os espectros de radiância das cores dos patches foram lidos de um arquivo texto e carregados na aplicação para servirem de entrada à função
corCIEXYZfromSurfaceReflectance. Para o cálculo dos valores sRBG de cada patch a partir de X, Y e Z, foi usada a função
corCIEXYZtosRGB.
Resumidamente, o programa está estruturado da seguinte forma: Ao iniciar, faz o carregamento do arquivo patches_spectra.txt com os espectros de radiância dos patches, bem como do arquivo patches_original_rgb.txt com os dados rgb originais extraídos do site do Bruce Lindblooom. Esses carregamentos e inicializações de vetores são realizados na classe ColorData.
Logo após o carregamento, o método computeColorChecker() calcula todos os valores sRGB do Color Checker através dos métodos do color.c citados acima. Os valores computados são armazenados em vetores e passados para a classe ColorCheckerRender, que cuida da renderização.
Na interface gráfica foi disponibilizado o botão "Alternar" para comparar visualmente os valores computados com os valores originais do Color Checker, na mesma posição. Também foi incluído um checkbox com a opção de mostrar os valores sRGB em cada patch.
Adaptação Cromática
Para um executável que usava o iluminante A, observou-se inicialmente uma grande discrepância nas cores, parecendo que estavam com uma matiz mais amarelada. Isso aconteceu porque o sistema sRGB é definido relativo ao iluminante D65. Por isso no método que converte um X,Y,Z para sRGB (corCIEXYZtosRGB), há matrizes de transformação relativas apenas ao branco de referência D65 ou ao D50(no caso do perfil ICC).
Para garantirmos que não haverá inconsistência entre os brancos de referência das cores XYZ e do usado no sistema RGB, foi preciso realizar a adaptação cromática, que converte o XYZ calculado com um dado iluminante, para outro iluminante. No caso deste programa, os XYZ calculados com o iluminante A tiveram de ser convertidos para XYZ referentes ao D65, para então sofrerem o cálculo do sRGB. Abaixo está o pequeno trecho de código inserido para essa adaptação.
Resultados
O programa desenvolvido mostra alternadamente dois Macbeth Color Checkers:
- Um chamado de
original, renderizado com as cores sRGB obtidas no site do Lindbloom(www.brucelindbloom.com), na seção Calc -> ColorChecker Calculator.
- E outro chamado de
computado, renderizado com as cores sRGB calculadas com os espectros e funções fornecidos.
O objetivo de se fazer essa alternância era o de comparar dois objetos na mesma posição da tela, tornando mais fácil a identificação de divergência nas cores.
Também há uma opção de exibir os valores sRGB nos patches, também para fins de comparação entre o original e o computado.
Os Color Checkers mencionados acima são os da figura abaixo.
Cores originais ------------- Computado com XYZ relativos ao D65 ----------- Computado com XYZ relativos ao A + Adapt.Cromática
A diferença das cores, tanto visualmente como nos valores, foi bem pequena. Entretanto, o esperado teoricamente era que fossem iguais, mesmo para iluminantes diferentes. Essa pequena diferença deve ser atribuída a fatores como precisão numérica ou intervalo de amostragem do espectro.
No pacote do programa encontram-se também duas imagens do Macbeth Color Checker para fins de comparação.
Raquel Jauffret Guilhon
14/04/2013