2.5 Tilpasset opplæring
2.5.1 Litt om begrepets utvikling
O processo de ajuste de brilho e cor é responsável por homogeneizar toda a imagem, oferecendo ao usuário a ilusão de uma única projeção contínua. A biblioteca de multiprojeção desenvolvida oferece tanto o ajuste de mistura de bordas (correção de sobreposição) quanto de cor. O processo de correção do brilho e da cor é realizado em duas etapas: (a) cálculo de participação dos projetores nas áreas de sobreposição e (b) correção de brilho e cor.
O cálculo de contribuição nas áreas de sobreposição é gerado logo após a correção geométrica e cada projetor obtém esta informação através de um mapa 2D com a contribuição de cada pixel do respectivo projetor. A correção de brilho e cor é processada em tempo de carregamento e execução da aplicação e utiliza as informações de contribuição nas áreas de sobreposição para auxiliar na correção. A seguir, serão detalhadas as correções de sobreposição e cor desenvolvidas para a biblioteca de multiprojeção.
3.4.2.1 Cálculo de sobreposição
O cálculo de sobreposição não faz nenhuma correção por si só, ele é utilizado apenas para auxiliar o processo de correção de brilho e cor (a ser discutido mais adiante).
Para obter a participação de cada projetor em uma região de sobreposição, calcula- se a relação entre os pixeis e a borda de cada projetor. Para facilitar a compreensão deste método, a figura 50 apresenta um pixel de intersecção e a sua distância para cada borda de cada projetor em um sistema formado por dois projetores horizontais.
Figura 50 – Participação de cada projetor
Para obter o mapa de contribuição para cada pixel de cada projetor, a eq. 22 demonstra o cálculo matemático utilizado pela biblioteca de multiprojeção para obter a contribuição de cada pixel, gerando o mapa de contribuições. Este algoritmo tem como base o algoritmo utilizado por Yang et al. (2001) e foi aperfeiçoado para melhorar a distribuição de processamento e qualidade visual.
∑ (22) Onde é a menor distância entre o pixel e uma determinada do . O é a quantidade máxima de projetores dentro da área de intersecção e a função retorna o menor valor.
Considerando que os projetores já estejam geometricamente alinhados e haja uma relação bidirecional entre projetor↔câmera, conforme descrito em “Mapeamento projetor↔câmera” (página 38), o algoritmo 5 demonstra a rotina desenvolvida para calcular o mapa de contribuição de cada projetor, tomando como base a eq. 22.
Algoritmo 5 – Cálculo de contribuição
Os mapas 2D gerados podem ser facilmente convertidos em imagem com tons de cinza, sendo que o branco representa 100% de contribuição e o preto representa 0% de contribuição. A figura 51 apresenta o mapa de contribuição gerado no exemplo apresentado na figura 49 (página 123).
Figura 51 – Mapa de contribuição
Adicionalmente, incorpora-se ao mapa – além da contribuição do projetor – a quantidade de projetores pertencentes a esta posição. Esta informação será utilizada no processo de correção de brilho e cor, discutido a seguir.
Para cada item de lista_projetores como p, faça:
{
Para cada coordenada x e y do projetor p, faça:
{
mínima_distância mínimo( x, p.largura - x, y, p.altura - y )
soma mínima_distância
(u,v) p.Projetor_para_Câmera(x,y)
Para cada item de lista_projetores como p2, faça:
{
Se( p igual p2 )
{
continuar // Próximo projetor
}
(x2,y2) p2.Câmera_para_Projetor(u,v)
Se( 1 ≤ x2 ≤ p2.largura e 1 ≤ y2 ≤ p2.altura ) // (x2,y2) p2
{
continuar // Próximo projetor
}
soma soma + mínimo( x2, p2.largura - x2, y2, p2.altura - y2 )
}
p.Mapa_Contribuição(x,y) mínima_distância / soma;
} }
3.4.2.2 Correção de brilho e cor
Após o cálculo do mapa de contribuição, as informações são utilizadas por cada projetor para realizar a correção de brilho e cor. Para isso, o Fast Fusion aplica uma função para cada pixel da imagem gerada pela aplicação, conforme apresentado no algoritmo 6.
Algoritmo 6 – Correção por pixel
A função de Correção_Brilho_Cor irá utilizar as informações do mapa de
contribuição e os coeficientes específicos deste projetor para calcular os novos valores de cor de cada pixel.
Atualmente, utiliza-se uma função exponencial para prover a suavização no trecho de transição (conforme apresentado no gráfico 7, página 66). Os coeficientes da função de transição são definidos individualmente para cada projetor. Além disso, uma função de gama (ver gráfico 8, página 68) individual para os três canais de cores (vermelho, verde e azul) também é configurada para cada projetor.
Uma terceira função polinomial corretora é aplicada durante a transição de sobreposição e utiliza a informação da intensidade luminosa, da quantidade de projetores e dos coeficientes variáveis para aprimorar a qualidade visual. O uso da quantidade de projetores é importante, uma vez que a intensidade de cada canal do projetor não é linear e as áreas de interseção com dois projetores apresentam resultados visuais diferentes em áreas de interseção com quatro projetores (estas geralmente mais escuras), mesmo adotando exatamente a mesma função de suavização.
Por fim, um último ajuste para cada canal de cor é aplicado em toda a imagem, independente das áreas de sobreposição, com objetivo de homogeneizar as cores entre os projetores. Estas informações são estabelecidas para cada projetor individualmente.
Para x de 1 até largura_tela, faça:
{
Para y de 1 até altura_tela, faça:
{
imagem_final[ x, y ] Correção_Brilho_Cor( imagem_aplicação[ x, y ],
mapa_contribuição,
coeficientes )
} }
Atualmente, o processo de obtenção dos coeficientes de brilho e cor utilizados pelo Fast Fusion é manual. Contudo, está previsto em sua arquitetura a obtenção automática destes coeficientes.
Uma vez obtidas todas as variáveis de calibração, estas serão utilizadas para corrigir cada pixel da imagem projetada. Tais correções devem ser aplicadas a cada quadro e podem afetar significativamente o desempenho da aplicação em razão dos cálculos necessários para cada pixel da imagem.
Para amenizar o impacto computacional, foi empregada uma textura de mistura, a qual é combinada com a textura da aplicação. É necessário criar a textura de mistura apenas uma única vez por calibração e, desta forma, embora exista uma carga de processamento inicial, todos os cálculos restantes são executados pela placa gráfica, o que diminui o impacto na aplicação.
O algoritmo 7 demonstra o modo através do qual o Fast Fusion gera a textura de mistura utilizando as primitivas OpenGL.
Algoritmo 7 – Geração de textura para correção de brilho e cor
Após gerada a textura de mistura (uma única vez logo após ao processo de calibração), basta aplicá-la sobre a textura da aplicação. O algoritmo 8 demonstra este processo.
Função Geração_Textura() {
// Criando e selecionando a textura de mistura.
glGenTextures( 1, textura_mistura )
glBindTexture( GL_TEXTURE_2D, textura_mistura )
// Definir valores de mistura.
Para x de 1 até largura_tela, faça:
{
Para y de 1 até altura_tela, faça:
{
buffer[ x, y ] Correção_Brilho_Cor( imagem_aplicação[ x, y ],
mapa_contribuição,
coeficientes )
} }
// Associando valores de mistura em textura de mistura
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, largura, altura, 0,
GL_RGBA, GL_UNSIGNED_BYTE, buffer );
Algoritmo 8 – Aplicação da textura para correção de brilho e cor
Embora esta técnica tenha pouco impacto sobre a aplicação, a função de mistura do OpenGL é linear, ou seja, não é possível aplicar funções complexas. Alternativamente, ainda pode ser desenvolvido um shader específico que suporta cálculos avançados de ajustes sem comprometer o desempenho. Está prevista a utilização de shader futuramente na biblioteca Fast Fusion.
A figura 52 apresenta o resultado do processo de correção do brilho e da cor final da biblioteca de calibração, seguindo o mesmo exemplo apresentado na figura 49 (página 123).
(a) (b)
Figura 52 – Exemplo de aplicação de correção de brilho e cor
A figura 52(a) apresenta o resultado após a calibração geométrica e a figura 52(b) apresenta o resultado após a calibração geométrica e a correção de brilho e cor.
Função Aplicar_Correção_Brilho_Cor() {
// Selecionando a textura de mistura.
glBindTexture( GL_TEXTURE_2D, textura_mistura )
// Definindo função de mistura.
glBlendFunc( GL_ZERO, GL_ONE_MINUS_SRC_COLOR )
// Aplicando a textura de mistura. glBegin( GL_QUADS ) glColor4f( 1, 1, 1, 1 ); glTexCoord2f( 0, 0 ); glVertex2f( 0, 0 ) glTexCoord2f( 0, 1 ); glVertex2f( 0, 1 ) glTexCoord2f( 1, 1 ); glVertex2f( 1, 1 ) glTexCoord2f( 1, 0 ); glVertex2f( 1, 0 ) glEnd() }