Curso de Realidade Aumentada e Colaborativa (2003.2)

Trabalho Final do Curso

Mestrado em Computação Gráfica da PUC-Rio

Luiz Gustavo Bustamante Magalhães (gustavo at tecgraf.puc-rio.br)
 

 

Descrição do Trabalho
Esta página foi gerada como resultado final do curso referenciado acima que foi ministrado pelo professor Marcelo Gattass do departamento de informática da PUC-Rio.

O objetivo deste trabalho era estudar técnicas (e implementá-las) para que fosse possível identificar um padrão pré-determinado em uma imagem (e também em uma seqüência de imagens) capturada através de um sistema de captura conhecido (no meu caso uma WEBCAM GO da creative) e com isso poder calibrar uma câmera para que possa ser inserido objetos virtuais na imagem, criando assim um ambiente de realidade aumentada.

Execução do Trabalho
Como primeiro passo para a execução do trabalho, tivemos como tarefa fazer um estudo sobre o sistema de captura que iríamos utilizar ao longo do trabalho. O objetivo deste estudo era entender melhor o funcionamento do sistema em si, determinar os parâmetros intrínsecos e extrínsecos do sistema de captura e descobrir anomalias inseridas na imagem pelo mesmo.

O sistema de captura utilizado foi a WEBCAM GO da Creative cuja foto pode ser vista abaixo:

 

 

As especificações fornecidas pelo fabricante técnicas sobre a câmera podem ser encontradas no seguinte documento:

Webcam_go.pdf

 

As especificações técnicas sobre o sensor de imagem CMOS utilizados por esta câmera podem ser encontradas no link abaixo:

Ov7610.pdf

 

Neste estudo foram realizados diversos testes: análise da distorção radial, variação de cosseno ^ 4 da luminosidade em relação ao centro da imagem, e análise de ruído. A distorção radial foi constatada, podendo ser perceptível simplesmente observando a imagem, mas não houve necessidade de uma correção neste sentido. A variação cosseno ^ 4 da luminosidade também foi observada, mas chegou-se à conclusão que o custo benefício para a implementação desta correção seria muito baixo ou praticamente inexistente. Vale ressaltar que para obtermos um resultado válido para avaliação deste ítem é importantíssimo que a iluminação seja perfeitamente uniforme. Com relação à análise de ruído, o que nos chamou mais a atenção foram os quadriculados observados na imagem do Ruído Normalizado. A princípio pensamos que era alguma deformação relacionada ao agrupamento dos sensores ou algo do tipo, mas posteriormente descobrimos que a grade observada está relacionada à compressão JPEG aplicada pela câmera automaticamente. O JPEG agrupa pixels da imagem em blocos para realizar a compressão, resultando então na grade discutida e que pode ser observada na figura abaixo:


Imagem Original


Ruído Normalizado

 

Uma apresentação com os resultados deste estudo pode ser encontrada no seguinte link:

apresentacao.ppt

 

Depois deste estudo, analisamos e implementamos alguns filtros para redução de ruídos (dentre eles o filtro da média e o gaussiano) e partimos então para a detecção das arestas. Foram estudados e implementados os filtros de sobel e log(laplaciano da gaussiana). O filtro de Canny não foi considerado pois sua implementação não tem performance muito boa. O filtro de sobel apresenta uma boa detecção de arestas, realçando as arestas realmente importantes, mas o seu principal problema é que as linhas encontradas ficam muito grossas(veremos porque isto é um problema posteriormente). Já o log apresenta linhas mais finas, mas muitas vezes as linhas desejadas não são detectadas; para corrigir este problema deve-se utilizar um threshold adequado para cada situação.Com relação à performance os filtros são equivalentes.

 

Em seguida, foi feito um estudo para a detecção de linhas na imagem. O primeiro algoritmo que testamos foi o de Hough, mas a sua aplicação na prática tornou-se inviável devido a sua baixa performance e também porque este método é muito sensível à variações na imagem. Além disso é necessário aplicar técnicas mais complexas e difíceis de ser calibradas como máximo local para eliminar o excesso de linhas detectadas em uma mesma região.

 

A partir deste ponto, e após uma aula do Flávio Szenberg sobre a sua Tese de doutorado, resolvi tentar estudar e botar para funcionar as idéias apresentadas pelo Flávio no meu trabalho. Os detalhes sobre a técnica utilizada por mim podem ser encontradas na tese do Flávio no link abaixo:

 

http://www.tecgraf.puc-rio.br/~szenberg/doutorado/index.html

 

Resumidamente, o algoritmo do Flávio para detecção de linhas baseia-se na divisão da imagem em pequenos blocos; descobre-se então a direção predominante em cada um desses blocos (se houver alguma), e agrupa-se os blocos próximos de mesma direção formando uma linha.

Posteriormente partimos para a interpretação das linhas seguindo um modelo. Primeiramente foi escolhido o Modelo 1 abaixo:

 

Mas foi encontrado um problema no modelo acima, pois as linhas da parte superior do U são dificilmente detectadas e estas são justamente as linhas mais importantes pois são elas que eliminam a simetria do modelo.

 

Resolvi então adotar o modelo que vi na tese do Flávio, pois ele é assimétrico e contém somente linhas grandes e facilmente detectáveis. Uma imagem do modelo pode ser vista abaixo:

 

Um outro problema que acontecia sempre era que a rotina de interpretação das linhas confundia as linhas das bordas da folha com linhas do modelo. Para resolver este problema, foi aplicada uma rotação no modelo antes da impressão.

 

Mas se ficarmos fazendo essa interpretação a todo frame, não iremos obter uma aplicação em tempo real nas máquinas atuais. Para contornar este problema é feito entre um frame e outro um ajuste de linhas de acordo com as linhas do frame anterior, dada uma faixa de tolerância. Isto resolve o problema quando a câmera está parada, mas o problema permanece se a movimentação da câmera é um pouco maior. Para resolver este problema faz-se uma predição do movimento segundo os 2 frames anteriores (isto está explicado em maiores detalhes na tese do Szenberg).

 

Depois disso, partimos para a calibração de câmera. O algoritmo utilizado foi o método de Tsai explicado em aula pelo professor e sua utilização não foi um problema visto que o Flávio nos forneceu um código com uma API bem modular e documentada. Vale lembrar que a função tsaiCalibration2D espera as coordenadas da tela em pixel com a origem (0, 0) no centro da imagem. Perdi algum tempo com isso!!! Quem mandou não ler a documentação ; )

 

O problema que o resto da turma teve com os erros no calculo que causam a trepidação do modelo são minimizados ou quase inexistentes na técnica da tese do Szenberg, portanto não senti necessidade de utilizar o filtro de Kalman para estabilizar o modelo.
 

Conclusão
O trabalho apresentou resultados satisfatórios, apesar de alguns problemas quando a movimentação da câmera ocorre de maneira rápida (mas não um corte seco).

 

Resumidamente, estes são os passos executados pelo programa:
- Filtro Gaussiano.

- Filtro Log.

- Detecção de linhas por divisão da imagem blocos.

- Interpretação das linhas segundo um modelo.

- Extração dos pontos relevantes do modelo (por interseção das linhas reconhecidas)

- Calibração de câmera (Método Tsai ).
 

A partir do segundo passo bem sucedido:

- Filtro Gaussiano.

- Filtro Log.

- Ajuste das linhas de acordo com as 2 homografias anteriores.

- Extração dos pontos relevantes do modelo (por interseção das linhas reconhecidas).

- Calibração de câmera (Método Tsai ).

 

Imagens
A seguir podemos ver algumas imagens do programa em execução:

 

 

 

Download

O arquivo do modelo 1 em formato Corel Draw (modelo1)
O arquivo do modelo 2 em formato Corel Draw (modelo2)
O código fonte com Solution do VC7 (imcapture)

Um binário(windows) para detecção do modelo 2 (binModelo2)

 

Agradecimentos

- Ao professor Marcelo Gattass pelas aulas.

- Ao Flávio Szenberg por me "emprestar" várias partes de seu código e por me ajudar na implementação (tirando dúvidas e, acredite se quiser, até debugar o programa ele me ajudou).

- Aos meus colegas pelas idéias e sugestões.

- Ao site www.gametutorials.com pelo módulo MD3 para a renderização do boneco no formato do Quake3.