Processamento e Estilização de Dados RGB-Z em Tempo Real

Tamanho: px
Começar a partir da página:

Download "Processamento e Estilização de Dados RGB-Z em Tempo Real"

Transcrição

1 Universidade Federal do ABC (UFABC) Centro de Matemática, Computação e Cognição (CMCC) Curso de Pós-Graduação em Ciência da Computação Dissertação de Mestrado Alicia Isolina Pretel Jesus Processamento e Estilização de Dados RGB-Z em Tempo Real Santo André, SP Março, 2014

2

3 Curso de Pós-Graduação em Ciência da Computação Dissertação de Mestrado Alicia Isolina Pretel Jesus Processamento e Estilização de Dados RGB-Z em Tempo Real Trabalho apresentado como requisito parcial para obtenção do título de Mestre em Ciência da Computação Orientador: João Paulo Gois Co-orientador: Harlen Costa Batagelo Santo André, SP Março, 2014

4 Este exemplar foi revisado e alterado em relação à versão original, de acordo com as observações levantadas pela banca no dia da defesa, sob responsabilidade única do autor e com a anuência de seu orientador. Santo André, 27 de Junhho de Assinatura do autor: Assinatura do orientador:

5 Centro de Matemática, Computação e Cognição (CMCC) Curso de Pós-Graduação em Ciência da Computação Processamento e Estilização de Dados RGB-Z em Tempo Real Alicia Isolina Pretel Jesus Março de 2014 BANCA EXAMINADORA: Prof. Dr. João Paulo Gois (Presidente) (CMCC) Universidade Federal do ABC - UFABC Prof. Dr. Helton Hideraldo Bíscaro (EACH) Universidade de São Paulo - USP Prof. Dr. André Guilherme Ribeiro Balan (CMCC) Universidade Federal do ABC - UFABC Prof. Dr. Jesús Pascual Mena Chalco (Suplente) (CMCC) Universidade Federal do ABC - UFABC Prof. Dr. Mario Augusto de Souza Liziér (Suplente) (GAPIS) Universidade Federal de São Carlos - UFSCAR

6 Este trabalho contou com o auxílio financeiro das seguintes entidades: Universidade Federal do ABC - UFABC (bolsa de mestrado, institucional), de fevereiro/2012 a janeiro/2013; Coordenação de Aperfeiçoamento de Pessoal de Nível Superior - CAPES (bolsa de mestrado, demanda social), de fevereiro/2013 a janeiro/2014.

7 Agradecimentos A Deus, pelo amor, pela saúde e por todas as coisas. Agradeço profundamente a meu esposo Jhon Franko Jorge Velarde, que é meu grande amor, obrigada pela motivação, compreensão, apoio e carinho que sempre me deu nos momentos mais difíceis e por todos os momentos que passamos juntos. Agradeço a minha família, pela força e por sempre depositarem suas esperanças em mim. Agradeço ao meu orientador e ao meu co-orientador, pela ajuda e colaboração com o meu trabalho, pelas conversas e conselhos ao longo do período do mestrado. A todos os professores pelas novas experiências, pelos desafios que me foram apresentados e pelos conhecimentos adquiridos. A meus amigos Lídia Rodrigues, Marcel Dias por sempre me motivar e torcer por mim. Agradeço a CAPES, e UFABC pelos financiamentos, em bolsas, para o desenvolvimento desta pesquisa. E por fim, agradeço a todos que um dia acreditaram em mim.

8 Resumo O desenvolvimento tecnológico de dispositivos de captura 3D nos últimos anos permitiram que os usuários acessassem dados 3D de forma fácil e com baixo custo. Neste trabalho estamos interessados no processamento de dados de câmeras que produzem seqüências de imagens (canais RGB) e as informações de profundidade dos objetos que compõem a cena (canal Z) simultaneamente. Atualmente o dispositivo mais popular para a produção deste tipo de informação é o Microsoft Kinect, originalmente usado para rastreamento de movimentos em aplicações de jogos. A informação de profundidade, juntamente com as imagens permite a produção de muitos efeitos visuais de re-iluminação, abstração, segmentação de fundo, bem como a modelagem da geometria da cena. No entanto, o sensor de profundidade tende a gerar dados ruidosos, onde filtros multidimensionais para estabilizar os quadros de vídeo são necessários. Nesse sentido, este trabalho desenvolve e avalia um conjunto de ferramentas para o processamento de vídeos RGB-Z, desde filtros para estabilização de vídeos até efeitos gráficos (renderings não-fotorrealísticos). Para tal, um framework que captura e processa os dados RGB-Z interativamente foi proposto. A implementação deste framework explora programação em GPU com o OpenGL Shading Language (GLSL). Palavras chave: dados RGB-Z, filtros de mapas de profundidade, processamento de vídeos RGB-Z, Scanners 3D, shaders.

9 Abstract The technological development of 3D capture devices in recent years has enabled users to easily access 3D data easily an in a low cost. In this work we are interested in processing data from cameras that produce sequences of images (RGB-channels) and the depth information of objects that compose the scene (Z-channel) simultaneously. Currently the most popular device for producing this type of information is the Microsoft Kinect, originally used for tracking movements in game applications. The depth information coupled with the images allow the production of many visual effects of relighting, abstraction, background segmentation as well as geometry modeling from the scene. However, the depth sensor tends to generate noisy data, where multidimensional filters to stabilize the frames of the video are required. In that sense this work developed and evaluated a set of tools for video processing in RGB-Z, from filters to video stabilization to the graphical effects (based on non-photorealistic rendering). To this aim, an interactive framework that captures and processes RGB-Z data interactively was presented. The implementation of this framework explores GPU programming with OpenGL Shading Language (GLSL). Keywords: RGB-Z data, filter depth maps, RGB-Z video processing, 3D Scanners, shaders.

10 Sumário 1 Introdução Motivação Objetivos e Contribuições desta Dissertação Trabalhos Relacionados Organização do Trabalho Processamento de Vídeo RGB-Z Captura dos Dados Preenchimento em Multirresolução Filtro Espaço-Temporal Efeitos sobre os Vídeos O framework Proposto Sistemas Gráficos com GPU, OpenGL e Shaders Componentes do Sistema O Microsoft Kinect Ferramentas Arquitetura do Sistema Ambiente de Teste

11 4 Desenvolvimento do Framework Descrição de Classes e Funções Relações das Classe nos Processos do Framework Interação dos Shaders Implementação de Shaders em GLSL Shaders do Preenchimento em Multirresolução Shaders do Filtro Espaço-Temporal Shaders para Nuvem de Pontos e Wireframe Phong Shading para Dados do Kinect Cartoon Shading Carregador de Arquivos Resultados e Discussão Utilização do Framework Resultados e Discussão Parâmetros Testados para cada Fase do Processamento Desempenho Limitações Discussões Contribuções Conclusões e Trabalhos Futuros Conclusões Trabalhos Futuros Referências Bibliográficas 110

12 Lista de Figuras 1.1 Processamento de dados RGB-Z Protótipo de câmera para dados RGB-Z Aplicações para dados RGB-Z Pipeline proposto para processamento de vídeo RGB-Z Reprojeção do mapa de profundidade às coordenadas de câmera de cor O Filtro Bilateral Amostras em sub-resolução da imagem Preenchimento em multirresolução Filtragem espacial e espaço-temporal Exemplo de Reiluminação Exemplo de Segmentação I Exemplo de Segmentação II Exemplo de Abstração Exemplo de Rendering Stroke-Based Exemplo de Rendering Estereoscópico Cartoon Shading O pipeline estendido de shaders O Kinect O padrão infravermelho

13 3.4 Modelo geométrico do Kinect Dados Kinect Arquitetura do sistema O framework Qt Diagrama de interação Interação dos shaders Fluxograma do rendering de um método Fluxograma de visualização da nuvem de pontos Fluxograma de visualização da malha como wireframe Fluxograma de visualização da superfície Faces triangulares com um ponto comum da malha Cálculo do vetor normal Uso do carregador de arquivos de shaders Interface gráfica Grupos de componentes da interface gráfica Interação com o mouse Barra de menus Opções de visualização da malha Processos de preenchimento de buracos Processos de filtragem espaço-temporal Processo de efeito especial Carregador de arquivos shaders Visualização com o mapa de profundidade filtrado Ativação do método fluxo óptico Posição da luz na cena Projeto Kinect Fun House Mirror

14 Lista de Tabelas 3.1 Especificações técnicas do hardware Bibliotecas e Ferramentas Níveis da Componente Difusa

15 Lista de Siglas Sigla Descrição API BF CBF DBF FBO GLSL GPU GPGPU JBU NPR OpenCV OpenGL OpenNI PCL TBO VAO VBO Application Programming Interface Bilateral Filter Cross Bilateral Filter Dual Bilateral Filter Frame Buffer Object OpenGL Shading Language Graphics Processing Unit General-Purpose Computing on Graphics Processing Units Joint Bilateral Upsampling Non-Photorealistic Rendering Open Computer Vision Open Graphics Library Open Natural Interaction Point Cloud Library Texture Buffer Object Vertex Array Object Vertex Buffer Object

16

17 Capítulo 1 Introdução O Microsoft Kinect é um dispositivo compito de sensores para a captura de movimentos para jogos do console Microsoft Xbox 360. Contudo, a utilização do Microsoft Kinect tem extrapolado o uso em jogos, uma vez que ele possui preço acessível e diversas APIs para o desenvolvimento de aplicações computacionais. Isto significa que novos desafios surgiram além do que era comumente usado em pesquisas de de nuvens de pontos [11, 13, 30] onde os dados eram obtidos principalmente por scanners inacessíveis a usuários domésticos [25]. Através do uso do Microsoft Kinect, foram propostas diversas aplicações, entre elas reconstrução 3D em tempo-real [32], desenvolvimento de ambientes de Realidade Mista [20, 18] e o processamento de vídeos em RGB-Z 1 [36]. Em particular, Richardt et al. apresentaram uma ferramenta de processamento de dados RGB-Z e um equipamento formado por uma câmera RGB e um sensor de profundidade time-of-flight [36]. Os autores propuseram filtros para a geração de imagens com coerência espaço-temporal e geometria simultaneamente. Na Figura 1.1 são apresentados os dados iniciais em (a) onde nota-se ruídos, em (b) a aplicação do filtro com coerência espaço-temporal, em (c) imagem original da cena e em (d) um rendering sobre a cena do modelo reconstruído. 1 Na bibliografia especializada, RGB-Z é também chamada de RGB-D.

18 Capítulo 1. Introdução 2 (a) (b) (c) (d) Figura 1.1: Processamento de dados RGB-Z: (a) mapa de profundidade 3D original (com ruído); (b) mapa de profundidade 3D filtrado; (c) Vídeo RGB original; (d) Vídeo RGB com rendering stroke-based (Fonte [36]).

19 Motivação Motivado pelo trabalho de Richardt et al [36], propusemos desenvolver uma ferramenta computacional que obtém, processa e cria efeitos visuais interativamente a partir de dados RGB-Z. Utilizamos os métodos de preenchimento e filtragem propostos por Richardt e colaboradores, porém buscamos considerar outros aspectos para garantir a interatividade da aplicação desenvolvida. A ferramenta aqui proposta é multiplataforma, desenvolvida com a Linguagem C++, com o Framework Qt 2 e com a linguagem de shaders do OpenGL (GLSL). Além disso, a interface gráfica da aplicação foi desenvolvida de modo que garantisse que os dados capturados em tempo real via o Microsoft Kinect fossem já processados e aplicados os efeitos especiais, ao passo que, na interface proposta por Richardt, o vídeo RGB-Z era gravado e carregado posteriormente para então se gerar os efeitos. A ferramenta aqui proposta apresenta outras funcionalidades, como a possibilidade de carregar os shaders em tempo de execução da aplicação, sem a necessidade de recompilar todo o código-fonte. Este recurso permite executar efeitos on-line. Por outro lado, a ferramenta proposta ainda possui algumas limitações, como a impossibilidade de gravação de resultados para reprodução posterior e nem a configuração de parâmetros das técnicas de processamento. 1.1 Motivação Embora há muita ênfase na Fotografia Computacional, existe um crescente interesse em desenvolver técnicas para processamento de vídeos, em especial para vídeos dotados de informação de profundidade (RGB-Z). Isto é devido ao avanço tecnológico de algumas câmeras com sensores especiais que além de capturar a informação de cor, capturam descontinuidades de profundidade em uma imagem, permitindo assim a criação de alguns dos efeitos mais atrativos na estilização do vídeo [36]. Além disso, existem ferramentas que fornecem uma interface para obter os dados em tempo real do Microsoft Kinect, tal como a Biblioteca Point Cloud Library 2

20 Capítulo 1. Introdução 4 PCL, um projeto open source para o processamento de nuvens de pontos. As principais tarefas em processamento vídeos são a elaboração de filtros espaço-temporal, métodos de super- amostragem e os efeitos especiais, por exemplo, rendering não foto-realístico, técnicas de re-iluminação, múltiplas visualizações, efeitos artísticos, mosaico, entre outras[15]. Contudo a implementação destas tarefas são dificultadas pelos seguintes problemas: P1. Obtenção de dados com o uso do Microsoft Kinect: o sensor de profundidade tende a gerar dados ruidosos e de baixa resolução. É por este fato que filtros multidimensionais (na intensidade, no espaço e no tempo) para estabilização dos frames do vídeo se fazem necessários; P2. Processamento em tempo real: desenvolver filtros e efeitos gráficos no vídeo com coerência espaço-temporal têm alto custo computacional. Desta forma, métodos interativos costumam explorar estruturas de dados sofisticadas e paralelismo. Desta forma se motiva a presente trabalho, enfatizando três características distintas: M1. Explorar os dados em RGB e de profundidade do Microsoft Kinect em conjunto com a biblioteca PCL; M2. Gerar vídeos RGB-Z com coerência espaço-temporal; M3. Desenvolver efeitos sobre imagens e vídeos RGB-Z explorando a linguagem GLSL [41]. 1.2 Objetivos e Contribuições desta Dissertação Embora neste projeto exploramos o método proposto por Richardt et al. [36] para a criação e manipulação de vídeo RGB-Z, o desenvolvimento de um Framework que satisfaz esses requisitos não é trivial. O Framework tem como finalidade receber dados diretamente do Kinect e processá-los em tempo real. O objetivo principal do Framework é explorar correspondências entre mapas de cor e de profundidade capturadas de modo a gerar vídeo RGB-Z coerente

21 Trabalhos Relacionados em tempo real, preenchendo áreas com oclusão e removendo ruídos. O resultado do vídeo é usado para o processo de rendering com diversos efeitos que exploram imagens e a geometria intrínseca da profundidade. O Framework desenvolvido no presente trabalho apresenta uma ferramenta interativa e multiplataforma. Ele foi desenvolvido em uma arquitetura que integra o uso de bibliotecas especializadas com o Qt (usando a Linguagem C++). Essa arquitetura é flexível o suficiente para permitir que novas pesquisas sejam englobadas e, simultaneamente, impor determinados padrões que permitam a integração de seus componentes. Modelos padrões são criados para a intercomunicação de dados entre CPU e GPU em todo o processo, esses modelos são definidos sobre o uso de estruturas da linguagem de shaders GLSL. 1.3 Trabalhos Relacionados Richardt et al. [36] apresentam um protótipo de hardware para capturar dinamicamente a imagem colorida e geometria da cena (mapas de profundidade), constituído por uma câmera de vídeo RGB e uma câmera de infravermelho (Infrared) IR Time-of-Flight ToF (Figura 1.2). Nas câmeras ToF a profundidade da cena é obtida através do tempo que leva um raio de luz emitido tocar um objeto e retornar para o detector da câmera. Existem câmeras com diferentes princípios para capturar mapas de profundidade, como aquelas baseadas em um sistema de luz estruturada. Essa técnica consiste na iluminação da cena feita pelo emissor de IR com uma faixa de luz conhecida e, na observação da mesma cena pela câmera de IR (posicionada em um ângulo conhecido em relação ao emissor de IR). O mapa de profundidade é obtido a partir da triangulação entre a câmera e o emissorde IR do equipamento [22]. Câmeras como o Microsoft Kinect, que possuem esta tecnologia, estão tendo muito impacto em diversas aplicações. Especificamente, o Microsoft Kinect tem sido aplicado no problema de Reconstrução 3D [32], Realidade Mista [18], [20] e Processamento de vídeos RGB-Z [36], [29]. A Figura 1.3 apresenta algumas aplicações nestas áreas. Dentre as aplicações mais populares temos o Ki-

22 Capítulo 1. Introdução 6 Figura 1.2: Protótipo de câmera para dados RGB-Z: câmera de vídeo RGB e câmera de infravermelho Time-of-Flight (Fonte [36]). nectfusion [32] Projeto de Reconstrução 3D em tempo real que cria uma estrutura volumétrica 3D e uma malha de polígonos que define a cena capturada, mesclado a partir de um conjunto de frames dos mapas de profundidade do Kinect. O modelo 3D resultante pode ser aplicado em Realidade Mista [18]. Já Knecht et al. [20] apresentam uma maneira atrativa de mostrar cenários de Realidade Mista, misturando objetos reais e virtuais considerando iluminação indiretamente entre eles (b). No processamento de vídeos RGB-Z, Richardt et al. [36] apresentam efeitos especiais nos vídeos tais como reiluminação, abstração, rendering stroke-based (Figura 1.1-(d)), segmentação e rendering estereoscópico 3D. Lucio et al. [29] mostram que à segmentação pode ser aplicado para a filtragem em certas regiões da cena, simulando o efeito especial de foco da câmera Figura 1.3-(c). São poucos os trabalhos que processam dados RGB-Z e que disponibilizaram seu códigofonte. Dentre alguns trabalhos podemos citar o projeto KinectFusion (Figura 1.3-(a)) e o projeto de Richardt e colaboradores. O KinectFusion, desenvolvido pela Microsoft Research, está disponível em uma versão open source chamado KinFu [16] que faz parte da biblioteca PCL. KinFu permite reconstruir uma cena em 3D e visualizar ela como malha ou como superfície densa com cores da textura RGB da mesma cena. Embora o KinFu mantenha alguns dos algoritmos de KinectFusion em CUDA (utilizando programação em GPGPU [19], permite fazer a ligação com eles e escrever código novo em C++. Já o projeto de Richardt et al. [36] processa

23 Trabalhos Relacionados (a) (b) (c) Figura 1.3: Aplicações para dados RGB-Z: (a) Reconstrução 3D e mapeamento de textura (Fonte [16]); (b) Realidade Mista, combinando luz e objetos virtuais com a cena real (Fonte [20]); (c) Efeito especial em vídeo RGB-Z, foco da câmera (Fonte [29]). vídeos RGB-Z, filtrando o mapa de profundidade e aplica efeitos no vídeo de cor. Os autores também disponibilizaram seu código-fonte, um conjunto de vídeos obtidos com o protótipo de câmera RGB-Z que eles criaram. Esse projeto foi implementado em C# com programação na GPU utilizando GLSL, mas apenas pode ser executado na plataforma Windows. Aplicações que usam como entradas dados RGB-Z, ou seja mapas de cor e de profundidade, visam como objetivo principal melhorar a qualidade do mapa de profundidade, além da execução em tempo real. As práticas nesse processamento são de superresolução (upsampling) e eliminação de ruído, assim a maioria dessas aplicações estão baseadas em uma extensão do Joint Bilateral Upsampling JBU. Nesse sentido, Garcia et al. [10] verifica que no uso comum de JBU [23], na fusão de imagens coloridas e mapas de profundidade, são gerados artefatos de textura que mostram falsas profundidades. Com a finalidade de evitar esses artefatos os autores propõem o método Pixel Weighted Average Strategy PWAS. Aqui os autores adicionam na aplicação do JBU uma estrutura chamada Mapa de Credibilidade MC, a qual é representada pela utilização de um kernel Gaussiano sobre os gradientes das profundidades vizinhas a um pixel. Com isto, o MC atribui maior peso para as verdadeiras transições de profundidade e rejeita a influência das bordas de cor. Do mesmo modo, Min et al. [31] apresentam o método Weighted Mode Filtering WMF.

24 Capítulo 1. Introdução 8 Com base no cálculo de um Joint Histogram JH para cada vizinhança de um pixel. A criação do JH está baseada no JBU e adiciona mais um peso definido por uma função Gaussiana de Erro (que é o desvio padrão da diferença de profundidade entre o pixel e cada um de seus vizinhos). Em seguida o resultado é usado para a contagem de cada valor de disparidade correspondente no mapa de profundidade. Também, para prevenir efeitos de aliasing os autores propõem aplicar seu método em escalas, eles referem-se ao método pelo nome de Multiscale Color Measure, e estende este método para conseguir consistência temporal, com uma estimativa simples de fluxo óptico [9] entre frames vizinhos. De maneira diferente às outras mencionadas, Vijayanagar et al. [40] utilizam um filtro multirresolução de difusão anisotrópica não-linear para fazer todo o processo de melhora dos mapas de profundidade. Os algoritmos que eles propõem exploram o conceito de pirâmides da imagem para refinar progressivamente o mapa de profundidade em diferentes resoluções. Os autores desenvolvem e implementam os algoritmos com programação em GPGPU utilizando OpenCL. Finalmente, o método de Richardt e colaboradores apresenta técnicas de preenchimento de buracos e filtragem em mapas de profundidade. A primeira técnica preenche áreas sem informação em vários níveis de resolução aplicando um JBU adaptado. A segunda técnica aplica um filtro espaço-temporal explorando coincidências das bordas de cor e de profundidade, a técnica considera dados do frame atual com dados filtrados no frame anterior, encontrando correspondências entre frames usando fluxo óptico. Em suma consegue-se dois objetivos: remoção considerável do ruído e superresolução do mapa de profundidade. Detalhes da técnicas de Richardt et al. [36] serão abordadas no Capítulo Organização do Trabalho O restante desta dissertação está organizada da seguinte forma: no Capítulo 2 são apresentadas as técnicas para o processamento de vídeo RGB-Z. No Capítulo 3 é apresentada a integração

25 Organização do Trabalho dos componentes do Framework assim como detalhes técnicos da arquitetura e de implementação. No Capítulo 4 é apresentado o desenvolvimento do Framework através da descrição de classes e funções bem como as suas relações. Além disto, é descrita implementação e interação dos shaders do processamento. No Capítulo 5 é apresentada a utilização do framework, resultados e discussões. Finalmente, no Capítulo 6 são apresentadas as conclusões do trabalho, além de sugestões para desenvolvimentos futuros.

26

27 Capítulo 2 Processamento de Vídeo RGB-Z O objetivo deste capítulo é apresentar em detalhes as etapas do processamento de Vídeo RGB- Z. Um vídeo RGB-Z é a combinação de vídeos de cor e de profundidade de uma cena. Consideramos a geração de um vídeo RGB-Z compreende a captura dos dados, a melhoria dos mapas de profundidade e a aplicação de um efeito especial. Vídeo Color Vídeo Profundidade Captura de Dados Preenchimento de Buracos Filtro Espaço-Temporal Efeito Especial Vídeo RGBZ Rendering Figura 2.1: Pipeline proposto para processamento de vídeo RGB-Z. Para as etapas de preenchimento e filtragem serão descritas as técnicas propostas por Richardt et al. [36]. Os métodos usados por eles buscam, no fim do processo, uma geometria suficientemente plausível em tempo real e adequados para aplicação de um rendering. Para alcançar esse objetivo foi proposto o pipeline que é mostrado na Figura 2.1. Na etapa de Captura de Dados (Seção 2.1), os vídeos de cor e de profundidades são capturados e transferidos como dados de entrada para o sistema. Também são preparados para processamento posterior. Na etapa de Preenchimento de Buracos (Seção 2.2), as áreas ocultas (sem informação) geradas

28 Capítulo 2. Processamento de Vídeo RGB-Z 12 pela diferença de distância entre as câmeras do dispositivo são preenchidas. Em seguida, na etapa de Filtro Espaço-Temporal (Seção 2.3) o ruído é removido mantendo correspondências entre sequências de frames que resultam em vídeos coerentes e estáveis ao longo do tempo. Finalmente, na etapa de Efeito Especial (Seção 2.4) é aplicado um tipo especial de rendering utilizando dados da cena (cor e geometria melhorada nas etapas anteriores). 2.1 Captura dos Dados A recuperação da geometria 3D dos objetos do mundo real é um dos problemas clássicos em Computação Gráfica e Visão Computacional. Os dispositivos para capturar essa geometria são comumente conhecidos como scanners 3D. Eles muitas vezes são equipados com luzes, projetores ou sensores. O resultado final dessa captura é uma descrição da geometria em termos de distância, profundidade, disparidade ou nuvem de pontos da superfície. A importância na captura de dados da geometria, ao contrário de uma imagem simples, é que esses dados fornecem acesso a muitas propriedades da superfície, úteis nos diferentes tipos de processamento, tais como vetores, normais e curvaturas. No presente trabalho, a aquisição dos mapas de profundidade é feita a partir do Kinect. Este equipamento contém uma câmera RGB, uma câmera e um emissor IR 1, sendo que os mapas de profundidade são obtidos a partir da triangulação de luz estruturada projetada (o suporte teórico e técnico do Kinect são explicados na Seção 3.2.1). Porém, as câmeras RGB e IR têm posições diferentes sobre o Kinect (um espaçamento de 2,5 cm entre elas), ou seja, para um pixel na imagem RGB existe uma posição diferente do mesmo pixel no mapa de profundidade, e por isso as imagens não estão alinhadas. Para corrigir esta diferença e alinhar vídeo de profundidade à projeção da câmera de cor é necessário usar o método de reprojeção [38]. Entretanto, esse método precisa dos dados da calibragem da câmera. No trabalho foram utilizados os dados alinhados fornecidos pela biblioteca PCL. Por conseguinte o método 1 A luz IR faz parte da porção invisível do espectro eletromagnético que está adjacente aos comprimentos de onda longos, por isso é luz não visível pelo olho humano.

29 Preenchimento em Multirresolução de reprojeção não será tratado. Para que os dados estejam prontos para a aplicação dos algoritmos do processamento, eles são transformados em um formato padrão como é descrito na Seção Preenchimento em Multirresolução Tanto as câmeras ToF [21] quanto as da luz estruturada, mesmo admitindo que elas sejam baseadas em tecnologias diferentes, geram imagens de profundidade que mostram áreas com oclusão de informação (em relação ao Kinect os motivos são descritos na Seção 3.2.1). Para esta etapa Richardt et al. [36] propuseram preenchimento de buracos em multirresolução. Essa etapa compreende um passo preliminar que é invalidar geometria nas bordas da profundidade para que logo seja aplicada a técnica de preenchimento de buracos. Os autores verificam que as câmeras ToF introduzem os chamados flying pixels que são descontinuidades de profundidade que flutuam em distâncias intermediárias e precisam ser removidos. Esses flying pixels são causados por imprecisões na estimativa de profundidade próprias do sensor, quando a área de um pixel cobre as superfícies a diferentes distâncias. No caso do Kinect, após reprojetar o mapa de profundidade às coordenadas de câmera de cor, justamente nas bordas onde existe diferença de profundidade, os dados resultantes apresentam texturas que nem sempre pertencem às suas respectivas profundidades. Tais texturas também precisam ser removidas (Figura 2.2). Por tal motivo, aplica-se limiarização à magnitude do gradiente de profundidade, utilizando o clássico Operador de Sobel [33]. O Operador de Sobel tem por finalidade detectar bordas em uma imagem. Tecnicamente, é um operador de diferenciação discreta em que o cálculo é uma aproximação do gradiente da função intensidade da imagem i. O Operador de Sobel é baseado na convolução da imagem com um kernel de tamanho 3 3. Esse kernel é separável porque aproxima as derivadas na

30 Capítulo 2. Processamento de Vídeo RGB-Z 14 Figura 2.2: Reprojeção do mapa de profundidade às coordenadas de câmera de cor. Note-se que a pessoa e a parede têm profundidades diferentes, mas nas bordas do rosto existem texturas da parede. direção horizontal G x e vertical G y : G x = * i G y = * i, onde * denota a operação de convolução bidimensional e i denota a função intensidade da imagem. As derivadas podem então ser combinadas para encontrar a magnitude absoluta do gradiente em cada ponto além da sua orientação. A magnitude do gradiente é dada por G = G 2 x + G 2 y. O limiar usado está no intervalo T = [0,1; 0,2]. Maiores valores levam a maior detecção de bordas. Por outro lado, o núcleo da estratégia para o preenchimento de buracos é baseado em uma extensão do Filtro Bilateral (Bilateral Filter BF). O BF é uma técnica de suavização nãolinear que preserva bordas [39] difere do Filtro Gaussiano porque considera que dois pixels

31 Preenchimento em Multirresolução são próximos um ao outro não só se ocupam posições espacialmente próximas, mas também se eles têm alguma similaridade na escala fotométrica (intensidade), como podemos observar na Figura 2.3. Portanto os pesos do seu kernel são modificados em função da semelhança da intensidade entre os pixels, dando assim maior peso para pixels pertencentes a regiões espacialmente próximas, e reduzindo o efeito de blurring das bordas onde descontinuidades fotométricas estão presentes. Figura 2.3: O Filtro Bilateral suaviza uma imagem de entrada preservando suas bordas. Cada pixel é substituído por uma média ponderada dos seus vizinhos, onde cada um é ponderado por um componente espacial que penaliza pixels distantes e um componente fotométrico que penaliza pixels com uma intensidade diferente. A combinação de ambas componentes assegura que apenas os pixels nas proximidades semelhantes contribuem para o resultado final (Adaptado de [6]). Especificamente para um pixel x em uma imagem colorida i o valor do BF é dado por: fbf (x) = 1 wc (x, y) w s (x,y) i(y), Kx y N (2.1) x Kx = wc (x, y) w s (x,y), (2.2) y Nx onde Nx é o conjunto de pixels vizinhos y no kernel centrado em x, e os pesos de cor e espaço são: ( ) wc (x, y) = exp i(x) i(y) 2 /2σ2c, (2.3)

32 Capítulo 2. Processamento de Vídeo RGB-Z 16 w s (x, y) = exp ( x y 2 /2σ 2 s). (2.4) Adams et al. [1] introduzem reformulam o BF representando o valor do pixel i(y) como uma quantidade homogênea, i.e. (r,g,b,1) em vez de (r,g,b). Desta forma, o propósito é aplicar a filtragem tanto na coordenada homogênea quanto nas demais, de modo que o resultado final seja dividido pelo valor da coordenada homogênea. Por conseguinte esta notação elimina a divisão normal pela soma dos pesos, e ela irá ser assumida a partir deste ponto. Assim: f BF (x) = w c (x, y) w s (x,y) i(y). (2.5) y N x Uma variação do BF, conhecida por Cross Bilateral Filter 2 CBF, foi introduzida por Eisemann e Durand [7] e Petschnigg et al. [35]. O CBF melhora a qualidade de uma imagem i usando uma segunda imagem ĩ da mesma cena. O filtro na intensidade da Equação 2.5 é aplicado em ĩ tentando combinar altas frequências de uma imagem e baixas frequências da outra. Portanto o peso de cor é substituído por: w c (x, y) = exp ( ĩ(x) ĩ(y) 2 /2σ 2 c). (2.6) A partir dos filtros anteriores, Kopf et al. [23] propuseram o Joint Bilateral Upsampling JBU para o problema de super-resolução, afirmando que informações adicionais estão disponíveis na forma da imagem original de entrada em alta resolução. Dada uma imagem em alta resolução ĩ, e uma imagem em baixa resolução S calculada para uma versão reduzida da imagem, é proposto um método que aplica um filtro bilateral durante o processo de Upsampling. O propósito é aplicar um filtro espacial para a solução em baixa resolução enquanto um filtro semelhante é aplicado no espaço da intensidade da imagem original; para o caso do projeto o 2 O Cross Bilateral Filter também é conhecido como Joint Bilateral Filter mas neste trabalho somente o denominaremos por CBF.

33 Preenchimento em Multirresolução JBU é definido como: f JBU (x) = w c (x, y) w s (x,y ) d(y ), (2.7) y N x onde x e y denotam coordenadas de pixels na imagem de alta resolução, e x e y denotam as coordenadas correspondentes em uma solução subamostrada do mapa de profundidade d(y ). Figura 2.4: Pirâmide de um conjunto hierárquico de amostras em sub-resolução da imagem. A técnica de preenchimento de buracos em multirresolução é justamente baseada no JBU, adaptado em diferentes escalas da imagem de cor e do mapa de profundidade (Figura 2.4). Para cada nível de resolução (da menor para a maior) calcula-se o CBF para preencher o mapa profundidade nesse nível. Após esta etapa, sobre esse resultado é aplicado o upsampling no nível seguinte e assim sucessivamente até alcançar o nível 0. O Algoritmo 1 descreve este método, onde os dados de entrada são o mapa de profundidade d e imagem de cor i, as duas de mesma resolução. No algoritmo se definem as variáveis n e g, nível de menor resolução (o nível de maior resolução é 0) e fator de sub-resolução, respectivamente. Também no mapa

34 Capítulo 2. Processamento de Vídeo RGB-Z 18 de profundidade toda região com dados sem informação é considerada inválida. Em primeiro lugar, as bordas do mapa de profundidade são invalidadas aplicando limiarização ao Filtro de Sobel (Linha 2). Em segundo lugar, do nível 0 até o n são calculadas as amostras em sub-resolução de d e i aplicando downsampling (Linhas 3 e 4). Em seguida, no último nível de resolução n é aplicado o CBF para preencher d n apenas em pixels inválidos utilizando os dados da imagem de cor (Linha 5). O resultado é d n. Logo após, do nível k = n até 1 (Linha 7 até 11), é gerada uma solução upsample u k 1 para o seguinte nível superior de resolução (Linha 8). Para isto utiliza-se d k e o mapa de profundidade do nível seguinte d k 1. No processo de upsampling os dados são preenchidos conforme d k 1, exceto quando nele existe dados inválidos. Nesse caso é preenchido com o correspondente dado do d k de acordo com o fator g. Ainda o resultado u k 1 contém dados escassos espalhados nas regiões inválidas. Após isso, apenas nos pixels inválidos de d k 1 é aplicado o CBF utilizando dados de u k 1 e i k 1 (Linha 9). Finalmente a saída de processo no nível 0 é o mapa de profundidade d R preenchido e sem buracos (Linha 12). Algoritmo 1 Preenchimento em multirresolução 1: procedure Preenchimento(d,i) 2: Calcular d 0 com kernel limiarização do gradiente de d. 3: Downsample d 0 : k {1,...,n} p d k calcular d k p = d k 1 p.k.g 4: Downsample i 0 : k {1,...,n} p i k calcular i k p = i k 1 p.k.g 5: d n p CBF (d n p,i n ), 6: k n p {q d n d n q = INVALID} 7: while k 1 do 8: u k 1 p.(k 1).g Upsample d k p, 9: d k 1 p.(k 1).g CBF (Uk 1 10: k k 1 11: end while 12: d R d 0 13: return d R 14: end procedure p.(k 1).g,Ik 1 ), p {q d k 1 d k 1 q p {q d k 1 d k 1 q = INVALID} = INVALID} A Figura 2.5 mostra graficamente a técnica descrita acima. As regiões amarelas representam dados inválidos. Nela o menor nível de resolução é 2. Nesse nível é feito um simples CBF.

35 Preenchimento em Multirresolução Para os seguintes níveis são aplicados os processos upsampling e CBF. Como já foi explicado, depois de ser aplicado o processo de upsampling ainda há dados escassos espalhados na região inválida. Esse resultado junto com a imagem de cor desse nível é utilizado no processo CBF apenas nos dados inválidos do mapa de profundidade do mesmo nível. No nível 0, depois de aplicar os processos, é obtido o mapa de profundidade preenchido. imagem cor mapa de profundidade preenchida (upsampling com dados escassos) mapa de profundidade Nível k = 0 i 0 d f 0 d u 0 d 0 Nível k = 1 i 1 d f 1 d u 1 d 1 Nível k = 2 i 2 d f 2 d 2 Figura 2.5: Preenchimento em multirresolução, com três níveis de escala, em pixels inválidos (cor amarela). O início do processo é no nível 2, onde aplica-se CBF. Para os outros níveis são aplicados upsampling e CBF. A saída do nível 0 é um mapa de profundidade preenchido (Adaptado de [36]). Esta abordagem pode ser implementada na GPU. Ela requer um parâmetro σ s 10 como tamanho do kernel de convolução. O σ s é um desvio-padrão da distribuição Gaussiana o qual quanto maior é seu valor, maior é o tempo para processar a imagem. No entanto, para um método simples de CBF [35, 7] é necessário um kernel com σ s > 25 para preencher buracos grandes com uma única resolução da imagem, o que torna muito lento o processo, impossível para processamento em tempo real (característica principal que procura-se em todos os

36 Capítulo 2. Processamento de Vídeo RGB-Z 20 métodos usados no Processamento de Vídeo RGB-Z), mesmo que seja executada na GPU. Adicionalmente, para reduzir a influência do ruído na imagem de cor, ela pode ser primeiramente filtrada usando BF com parâmetros σ s = 3 e σ c = 0,1. Porém, aplicar esse filtro exige um tempo extra de cálculo no processo completo. 2.3 Filtro Espaço-Temporal Bennett et al. [4] introduziram o Dual Bilateral Filter DBF como uma outra variante do BF e do CBF. Tanto o CBF como o DBF precisam de duas imagens como entrada. Contudo, o DBF modifica a obtenção do peso da intensidade, que neste caso é representado pelo espectro visível (RGB) e pelo espectro infravermelho (IR), o último representado no mapa de profundidade d. A câmera IR capta mais bordas, mas não tem as cores de uma câmera padrão RGB. Neste contexto, a dupla força do DBF faz com que as propriedades de ruído das imagens de entrada sejam contabilizadas separadamente, através dos parâmetros independentes σ c e σ d (Equações 2.9 e 2.10, respectivamente). Assim o DBF é um filtro espacial que preserva as bordas na imagem colorida i(x) e o mapa de profundidade d(x). A profundidade filtrada espacialmente em um pixel x num intervalo de tempo t é dada por: f s (x, t) = w c (x, y) w d (x, y) w s (x, y) d(y, t), (2.8) y N x onde N x é o conjunto de pixels do kernel com raio 2σ s centrado em x, e os pesos de cor, distância e espaço são: w c (x, y) = exp ( i(x, t) i(y, t) 2 /2σ 2 c), (2.9) w d (x, y) = exp ( d(x, t) d(y, t) 2 /2σ 2 d), (2.10) w s (x, y) = exp ( x y 2 /2σ 2 s). (2.11)

37 Filtro Espaço-Temporal O trabalho de Richardt et al. [36] aplica esse filtro no mapa de profundidade. Neste caso o resultado mostra-se na Figura 2.6-(b), comprovando que o ruído é suavizado, mas ainda não é eliminado completamente. Isto se deve ao fato de não lidar com ruído residual de baixa frequência que ainda é visível. Os valores dos parâmetros do filtro usados pelos autores são σ c [0,05; 0,1], σ d [0,075; 0,1] e σ s [4; 8]. (a) sem filtragem (b) filtragem espacial (c) filtragem espaço-temporal Figura 2.6: Comparação dos filtros espacial e espaço-temporal (Fonte [36]). Richardt e colaboradores assumem que o ruído de um frame em um intervalo de tempo é independente de outro, mas pode ser reduzido pela média de frames anteriores. Contudo, se pixels de frames anteriores forem simplesmente reutilizados, distorções visíveis podem aparecer. O que significa que qualquer movimento da câmera ou alterações na cena pode resultar em ghosting trails [17] seguindo os objetos. Esse efeito pode ser compensado através do fluxo de movimento, calculando os deslocamentos dos pixels entre osframes. Assim, considerando dois frames sucessivos com movimento significativo entre eles (deslocamentos dos pixels), temos que para o processo de filtragem espaço-temporal do frame atual, o filtro deve ser compensado com esse movimento significativo em relação ao frame prévio, além de considerar filtragem espacial. Com isto, esse filtro é mais efetivo na eliminação de ruído espacial e temporal. Portanto, para estabilizar cada frame de um mapa de profundidade no intervalo de tempo t, o filtro

38 Capítulo 2. Processamento de Vídeo RGB-Z 22 espaço-temporal no pixel x é dado por: f S T (x, t) = (1 ϕ) f S (x, t) + ϕ f T (x, t), (2.12) onde o filtro espaço-temporal é compensado no movimento por f T propagando as distâncias filtradas de um frame prévio no intervalo de tempo t 1 ao frame atual no intervalo de tempo t. No filtro temporal, x em t 1 denota a localização do movimento compensado de x no t. Então f T é calculado como: f T (x, t) = w (x, y, x, ȳ) f S T (ȳ, t 1). (2.13) y N x A Equação 2.13 visa reduzir as oscilações provocadas pelo ruído independente do tempo. Para isto combina pesos com o mapa de profundidade filtrado em t 1 em localizações do movimento compensado ȳ de todos os pixels y do kernel. Os pesos do filtro são dados por: w (x, y, x, ȳ) = w c (x, ȳ) w d (x, ȳ) w s ( x, ȳ) w f (y, ȳ). (2.14) A Equação 2.14 avalia a similaridade do pixel de movimento compensado ȳ com o pixel central x, em termos de distância, cor e espaço. No entanto, o peso espacial w s não penaliza a distância de x, mas sim sua localização de movimento compensado x. O peso de fluxo w f é definido na Equação O objetivo desse peso é reduzir a influência de dados antigos em áreas de movimento rápido como eles tendem a ser não confiáveis. Com σ f [4; 5], temos: w f (y, ȳ) = exp ( y ȳ 2 /2σ 2 f ). (2.15) Além disso, para prevenir a amplificação do ruído nas áreas de movimento rápido, o filtro espacial f S é aumentado redefinindo o peso da intensidade como: w c (x, y) = exp ( g c i(x, t) i(y, t) 2 /2σ 2 c), (2.16)

39 Efeitos sobre os Vídeos usando g c = [ ] 1 2 ȳ y /σ f onde 0 [m]b a fixa m ao intervalo [a,b]. O resultado é observado nas áreas de movimento rápido da cena, onde se incrementa a importância da filtragem espacial e as distâncias são suavizadas por meio das bordas da imagem de cor. Em relação a encontrar os valores de x e ȳ no intervalo de tempo t 1, que são as localizações do movimento compensado de x e y no intervalo de tempo t, se utiliza Fluxo Óptico, responsável por calcular essas correspondências de pixels entre frames. Neste caso, são utilizados 2 frames consecutivos das imagens de cor. Esse processo é implementado na GPU como no trabalho de Eisemann et al. [8]. Finalmente, o filtro f S T é a soma do filtro espacial f S com o filtro temporal f T equilibrado pelo parâmetro ϕ. Esse parâmetro define pesos cuja soma é 1. O maior peso é dado para o filtro no frame atual, f S, e ϕ [0,01; 0,1]. Da mesma forma, o filtro espaço-temporal serve para aumentar a resolução dos mapas de profundidade (como é o caso dos mapas de profundidade de baixa resolução obtidos com câmeras ToF). Porém no presente trabalho não precisaremos aplicar este processo porque o Kinect fornece mapas de profundidade e de cor com mesma resolução (Seção 3.2.1). 2.4 Efeitos sobre os Vídeos Logo após a etapa de filtragem, é obtido um mapa de profundidade de alta qualidade. Ele está pronto para, junto com a imagem de cor, ser usado na aplicação de um efeito especial no vídeo RGB-Z. Muitos algoritmos de estilização da imagem precisam de informação útil para identificar os limites e formas de objetos na cena. Uma imagem de cor pode apresentar efeitos naturais de sombra e de iluminação do ambiente. Por exemplo, no problema fundamental da segmentação automática de objetos [5], torna-se complexo e difícil para o computador saber na imagem quais bordas representam limites e quais são causadas por descontinuidades internas de textura. Nesse sentido, as descontinuidades de profundidade desempenham um papel fundamental pois

40 Capítulo 2. Processamento de Vídeo RGB-Z 24 fornecem informações sobre a geometria da cena e propriedades como normais, gradientes e curvaturas. Esses dados aliados aos vídeos de cor podem criar efeitos atrativos. Muitos destes efeitos podem ser gerados por um certo número de estilos expressivos pertencentes ao rendering não-fotorrealístico NPR (Non-Photorealistic Rendering). NPR explora diferentes estilos artísticos mudando a informação visual [24] que em muitos casos a saída do rendering reduz a quantidade de informações que devem ser percebidas pelos usuários. NPR pode ser aplicado à fotografia, vídeo e geometria (objetos 3D). Dentre as técnicas ou efeitos de NPR que podem ser aplicados usando a geometria da cena e imagens de cor, ou seja, vídeo RGB-Z, temos: Reiluminação: com o mapa de profundidade pode-se calcular a normal para cada pixel pertencente à cena. Usando essa normal bem como a posição 3D de uma fonte de luz, é possível modificar a intensidade do pixel em função do ângulo entre elas. O modelo de iluminação Phong [2] é o mais popular método de tonalização de malhas poligonais (Figura 2.7); Figura 2.7: À esquerda imagem original, as seguintes imagens mostram efeitos de Reiluminação com diferente posição da fonte de luz (Fonte [27]). Segmentação: como dito anteriormente as descontinuidades de profundidade fornecem informações úteis para a identificação de limites do objeto. Essas informações combinadas com informações RGB tornam possível a segmentação automática de objetos

41 Efeitos sobre os Vídeos produzindo uma silhueta precisa de eles. Alguns exemplos deste efeito são apresentados nas Figuras 2.8, 2.9 e 1.3-(c); Figura 2.8: À esquerda, mapa de profundidade do objeto. À direita, segmentação do objeto (Fonte [26]). Figura 2.9: À esquerda, imagem de cor da cena. No centro, mapa de profundidade. À direita segmentação em capas (Fonte [5]). Abstração: técnica que explora a geometria da cena e, coloca linhas nas formas da geometria que são significativas (Figura 2.10); Stroke-Based Rendering: é um efeito que distribui strokes (traços) que cobrem a área dos objetos na imagem. No entanto, em vez de orientar esses strokes ao longo de gradientes da imagem, eles são orientados às curvaturas principais do mapa de profundidade que permitem alinhá-los às características geométricas significativas (Figura 2.11); Rendering Estereoscópico 3D: a idéia para a esse efeito é sintetizar duas vistas, um para cada olho. Os vídeos RGB-Z podem servir para aplicar rendering estereoscópico para

42 Capítulo 2. Processamento de Vídeo RGB-Z 26 Figura 2.10: À esquerda imagem original, à direita abstração (Fonte [36]). Figura 2.11: À esquerda, imagem original. À direita, Rendering Stroke-Based (Fonte [28]).

43 Efeitos sobre os Vídeos melhorar a percepção de profundidade da cena. Um exemplo deste efeito é mostrado na Figura 2.12; Figura 2.12: Exemplo de Rendering Estereoscópico (Fonte [34]). Cartoon Rendering: ou efeito Cartoon Shading, é uma técnica que pretende imitar o estilo de sombreamento frequentemente usado em desenho animados. Existem muitos métodos que são usados para produzir este efeito. Wolff [41] mostra um método que envolve uma pequena modificação no método de tonalização Phong. O efeito básico é ter grandes áreas de cor constante com transições nítidas entre elas, ou seja, a cor é restrita a poucos níveis (Figura 2.13). Isso simula a maneira que um artista pode dar sombra em um objeto usando pinceladas de uma caneta ou pincel. Além disso, o efeito inclui contornos pretos ao redor das silhuetas e ao longo de outras bordas de alguma forma existente na cena.

44 Capítulo 2. Processamento de Vídeo RGB-Z 28 Figura 2.13: À esquerda, tonalização Cartoon Shading com dois níveis. À direita, Phong Shading.

45 Capítulo 3 O framework Proposto Dadas as características da pesquisa em testar e comparar algoritmos de filtragem e estilização nas imagens dos vídeos RGB-Z em tempo real, onde os dados são obtidos a partir de uma câmera scanner 3D, é útil ter um sistema que auxilie a configuração e a execução de experimentos nos gráficos. Com a finalidade de atender essa situação, neste trabalho foi proposto um framework que proverá uma infraestrutura capaz de integrar seus componentes e executar diferentes configurações de experimentos. Em detalhes esse framework contém: um mecanismo de integração entre dispositivo de entrada, bibliotecas externas e uma interface gráfica intuitiva; a disponibilidade do código fonte em uma linguagem baseada em C++ e uso de shaders em GLSL; um ambiente de execução multi-plataforma com resultados gerados em tempo real. Este capítulo tem como objetivo descrever a integração dos componentes do sistema, assim como detalhes técnicos e de implementação do framework. O restante deste capítulo está organizado da seguinte maneira: na Seção 3.1 é apresentada uma visão geral de um Sistema Gráfico com GPU, OpenGL e shaders. Na Seção 3.2 são descritas as componentes de integração do

46 Capítulo 3. O framework Proposto 30 sistema tais como dispositivos de entrada, bibliotecas externas, ferramentas e linguagem de programação usada. Na Seção 3.3 é apresentada a arquitetura do sistema e, finalmente, na Seção 3.4 é descrito o ambiente de teste do sistema. 3.1 Sistemas Gráficos com GPU, OpenGL e Shaders O desenvolvimento da Computação Gráfica tem sido impulsionado pelas necessidades de avanços em hardware e software. Desde o ano 2000 destacam-se progressos importantes como por exemplo, conseguir o fotorrealismo em tempo real com o uso de pipelines programáveis na Graphics Processing Unit GPU. Tal objetivo pode ser possível com a combinação de fatores tais como conceitos modernos de Computação Gráfica, uso de APIs gráficas e programação na GPU. Os sistemas gráficos modernos enviam da CPU para GPU informações da cena em forma debuffers de atributos de vértices e buffers de índices aos vértices. Na GPU é feito o processo de rendering. Esse processo é suportado em uma arquitetura pipeline para gráficos raster, a qual armazena os pixels de saída no frame buffer [2]. A arquitetura do pipeline para sistemas gráficos inclui, entre outros, um processador de vértices, geometria e fragmentos. O pipeline habilita aplicar operações com vértices, primitivas e pixels. As GPUs evoluíram e são caracterizadas por módulos de propósito específicos voltados para operações gráficas e com alto grau de paralelismo. Assim, as arquiteturas das GPUs já estão modeladas para dar suporte ao pipeline definido na Figura 3.1. Uma aplicação na GPU pode ser programada o processador de vértice, geometria e fragmento. Dentre AS funcionalidades que permitem um grande poder computacional na GPU, temos as múltiplas unidades de processos matemáticos, acesso rápido à memória integrada, execução de um programa por cada fragmento/vértice e tarefas paralelas de alto desempenho. A GPU pode estar localizada na placa principal ou em uma placa gráfica. Atualmente, as principais fabricantes de GPUs no mercado são a NVIDIA e a ATI.

47 Sistemas Gráficos com GPU, OpenGL e Shaders Vertex Shader Primitive Assembly Tessellation Control Shader Tessellation Primitive Generator Tessellation Evaluation Shader Primitive Assembly Geometry Shader Primitive Assembly and Rasterization Fragment Shader Figura 3.1: Pipeline estendido de shaders suportado por OpenGL, em versões posteriores à 4.0 (Fonte [41]). Por outro lado OpenGL 1 é uma API gráfica independente da plataforma e de fácil uso, que fornece uma interface de software que divide o trabalho para cada comando OpenGL entre a CPU e a GPU. As versões modernas estão baseadas na utilização de shaders programáveis para realizar o rendering na GPU, e estão sendo estruturadas em torno do pipeline para sistemas gráficos. Já para versões mais modernas do OpenGL foram adicionadas a esse pipeline o Geometry e Tessellator Shader como se mostra na Figura 3.1. Uma das opções para se escrever shaders é pela linguagem GLSL, que tem uma especificação separada do OpenGL, embora as funções de interface com aplicação para shaders façam parte da API OpenGL. Os shaders podem executar na GPU algoritmos relacionados com a iluminação e efeitos de tonalização de uma imagem 3D. No entanto, os shaders também são capazes de realizar animação [3], tessellation [41], e até cálculo de propósito geral (GPGPU) 2. O pipeline da Figura 3.1 mostra as fases programáveis que são encapsuladas em shaders.o pipeline estendido de shaders adiciona o Tessellation Control Shader TCS, Tessellation Evaluation Shader TES e Geometry Shader GS. Basicamente GS é projetado para executar uma vez para cada primitiva. Ele tem acesso a todos os vértices da primitiva, bem como os valores de todas as variáveis de entrada associados com cada vértice. O uso de TCS e TES apresenta recursos para alterar a topologia e a geometria da malha. Por último, OpenGL fornece estruturas que gerenciam o armazenamento dos dados na GPU dentre os mais importantes e usados neste trabalho estão aqueles que manipulam objetos 1 O desenvolvimento é controlada por Kronos Group 2 Tais como dinâmica de fluidos, dinâmica molecular, criptografia, e assim por diante, que muitas vezes usam APIs especializadas, como CUDA ou OpenCL.

48 Capítulo 3. O framework Proposto 32 buffer denominados Vertex Buffer Object VBO, contêineres de objetos vértices denominados Vertex Array Object VAO, texturas unidimensional denominadastexture Buffer Object TBO, rendering de imagens denominados Frame Buffer Object FBO. A última estrutura é interessante porque permite aplicar render-to-texture, que serve para escrever os resultados de um à memória de modo que, em seguida, pode ser utilizado como entrada em outras passagens pelo pipeline gráfico. 3.2 Componentes do Sistema Nesta seção vamos apresentar as componentes do sistema. Primeiramente apresentaremos o hardware utilizado, Kinect. Em seguida apresentaremos a arquitetura dos softwares que representam a estrutura de base que irá apoiar o desenvolvimento e funcionamento do framework. Figura 3.2: O Microsoft Kinect O Microsoft Kinect No presente trabalho, o dispositivo de entrada para a aquisição das imagens de cor e dos mapas de profundidade é feita a partir do Microsoft Kinect. Kinect foi apresentado em novembro de 2010, como um acessório para console Xbox 360, desenvolvido pela empresa PrimeSense em colaboração com a Microsoft. Em fevereiro de 2012, uma versão para Windows foi lançada. Os dados adquiridos têm naturezas diferentes e complementares, combinando geometria com atributos visuais. Por esta razão, o Kinect é uma ferramenta flexível que pode ser usada em aplicações de diversas áreas, tais como: Computação Gráfica, Processamento de Imagens,

49 Componentes do Sistema Visão Computacional e Interação Humano-Computador. A plataforma Kinect abrange tecnologias como uma câmera RGB, sensor de profundidade em 3D, microfone e uma inclinação motorizada (Figura 3.2). O sensor de profundidade da câmera IR do Kinect está baseada na tecnologia de luz estruturada. A técnica para capturar os mapas de profundidade é suportada por um modelo geométrico. Figura 3.3: O padrão infravermelho é organizado como matriz 3 3 de pontos. Pode-se ver que cada parte é diferenciada pela intensidade e têm um ponto de registro centralizado. Modelo geométrico: O mapa de profundidade é obtido a partir da triangulação feita entre o emissor IR e a câmera receptora do equipamento, como mostrado na Figura 3.4. Essa técnica consiste na iluminação da cena feita pelo emissor, com uma faixa de luz conhecida que é o padrão infravermelho (Figura 3.3), e na observação da mesma pela câmera posicionada em um ângulo conhecido em relação ao emissor IR. A posição tridimensional dos pontos da cena é determinada a partir da interseção entre a direção da visão da câmera e a direção da luz produzida pelo emissor. Aquisição dos dados: Dentre os dados que o Kinect provê temos a imagem RGB, mapa de profundidade e a imagem IR (mostrados na Figura 3.5). Mas no presente trabalho utilizamos apenas as imagens RGB e os mapas de profundidade. Sensor de Profundidade: O sensor de profundidade 3D consiste em um projetor de laser infravermelho, que capta profundidade em qualquer condição de iluminação,

50 Capítulo 3. O framework Proposto 34 X R, T Z Y X C IR C RGB C Projetor 2.5 cm b=7.5 cm Figura 3.4: Modelo Geométrico do Kinect: C IR, C RGB, C Pro jetor são as câmeras IR, RGB e emissor IR. A localização X é determinada a partir da interseção entre a direção da visão da C IR e a direção da luz produzida pelo emissor da C Pro jetor. R,T são os parâmetros de Rotação e Translação usados para projetar dados da visão da C IR à visão da C RGB (Adaptado de [38]). fornecendo informações detalhadas sobre o meio ambiente. Juntos, o projetor e o sensor criam um mapa de profundidade baseado no modelo geométrico. Esse sensor tem um limite prático de distância variando de 0.8 a 3.5 metros. Contudo, a qualidade da medição de profundidade é afetada se o laser é projetado fora de um quarto; ou seja, o sensor IR do Kinect se torna não confiável na presença de luz solar porque a luz IR do sol se sobrepõe à luz IR ou pulso emitido a partir do sensor. A câmera IR opera em 30 Hz proporcionando mapas de profundidade de pixels com uma precisão de 11 bits. Neste caso, os dados de profundidade podem ser considerados como imagens com um único canal, ou seja, podem ser convertidos em imagens monocromáticas. Câmera RGB: Ela produz vídeo de cor a 30 Hz, também com uma resolução máxima de pixels, com 32-bits, ou seja, 8-bits por canal RGB.

51 Componentes do Sistema (a) (b) (c) Figura 3.5: Dados gerados pelo Kinect: (a) Imagem RGB; (b) Mapa de profundidade; (c) Imagem IR. As câmeras de luz estruturada têm a vantagem de prover mapas de profundidade densos com alta precisão em relação às câmeras ToF e às utilizadas para visão estéreo [38]. Em compensação, as imagens de profundidade obtidas por tal sistema têm as desvantagens de ruído e regiões sem dados (em uma imagem de profundidade são refletidas em cor preto). Isto é causado por várias razões: curta distância entre o objeto e o sensor, falta de reflexão de luz de alguns objetos, superfícies especulares, superfícies refinadas como o cabelo humano, a orientação da superfície frente ao eixo principal da câmera IR, pois as normais sofrem desvios e a medição se torna pouco confiável perto de descontinuidades de profundidade e disparidade entre o projetor eo sensor Ferramentas Abaixo estão descritas as ferramentas e tecnologias utilizadas no framework. O framework Qt O framework Qt permite o fácil desenvolvimento de aplicações gráficas profissionais multiplataforma usando C++. Qt fornece módulos compatíveis com OpenGL e GLSL, ou seja, proporciona um conjunto completo de recursos para programação em GPU [12]. Com o Qt, matrizes, vetores, objetos de buffer de vértices, texturas, shaders e componentes de interface

52 Capítulo 3. O framework Proposto 36 do usuário são integradas por classes no paradigma orientado a objetos e intercomunicam-se pelo mecanismo Qt de signal/slots. As bibliotecas Qt e ferramentas estão reunidas no Qt SDK. Qt também fornece uma IDE, denominada Qt Creator. Ela é uma solução completa para o desenvolvimento UI (User Interface). Disponível para Windows, Linux e Mac OS X, Qt é open source e disponível sob licenças diferentes, incluindo GNU LGPL 2.1, GNU GPL 3.0 e uma licença para desenvolvimento comercial. Bibliotecas Dentre as bibliotecas escolhidas neste trabalho e que suportam e fornecem funcionalidades para o desenvolvimento de aplicações para o Kinect, estão o PCL, OpenNI e OpenCV. PCL. Point Cloud Library 3 PCL é um projeto open source em grande escala para imagens 2D/3D e para o processamento de nuvens de pontos. Ele é liberado sob a licença BSD e é livre para uso comercial e de pesquisa. PCL é destinada para ser uma biblioteca multiplataforma. Para a aquisição de dados o PCL fornece interface para a API OpenNI. PCL é integrado com o Visualization Toolkit VTK [37]. PCL contém algoritmos para filtragem, reconstrução da superfície, registro de movimentos da câmera, segmentação, extração de características, registro, busca por vizinhanças, manipulação de entrada e saída entre outras. OPENNI. Open Natural Interaction 4 OpenNI, é um framework open source multi-linguagem e multi-plataforma cujo objetivo principal é oferecer um padrão que permita a comunicação com sensores visuais e de áudio. A API do OpenNI elimina a dependência entre os sensores e middleware, permitindo que os aplicativos sejam escritos sem esforço adicional em cima dos módulos diferentes de middleware. A OpenNI permite também que as aplicações sejam escritas independentemente do tipo de sensor e dos fornecedores de

53 Arquitetura do Sistema middleware, o que torna possível a utilização de muitos dispositivos de captura disponíveis 5 publicamente, como PrimeSense PSDK, Microsoft Kinect, Asus XtionPro. OPENCV. A Open Computer Vision 6 OpenCV é uma biblioteca open source livre sob a licença BSD e multi-plataforma. OpenCV é uma biblioteca bem estabelecida para Visão Computacional 2D, mas também coloca em seus algoritmos métodos para dados 3D. 3.3 Arquitetura do Sistema A arquitetura é a estrutura base da implementação do sistema, representado no modelo de estrutura de fluxo de dados que define componentes que interagem uns aos outros. O sistema foi subdividido de forma que cada grupo de funcionalidades possuísse um modulo específico que as implementasse. A Figura 3.6 mostra o diagrama componente conector do sistema. O componente DepthProcessing é responsável por lidar com todas as operações que são feitas com os mapas de profundidade. Esse componente carrega um mapa de profundidade a partir do componente PCL que trabalha internamente com a biblioteca OpenNI para capturar dados do Kinect. PCL fornece os dados em arrays tipo uchar com formato de 16 e 32 bits para mapas de profundidade e imagens de cor, respectivamente. A biblioteca OpenCV é responsável pela conversão dos dados originais em formato IplImage para manipulação e processamento das imagens. A descrição das bibliotecas é abordada na Seção O mesmo componente também é responsável pela melhora do mapa de profundidade com a aplicação de processos na GPU como preenchimento de buracos e filtragem, usando as técnicas de limiarização de Sobel, downsampling, upsampling, filtro Joint Bilateral, fluxo óptico e filtro espaço-temporal. Cada processo na GPU usa um Programa Shader dividido em Vertex Shader e Fragment Shader para realizar as respectivas tarefas de transformações e rendering. Esses conceitos são descritos na Seção 3.1. A saída de cada processo permanece na memória da GPU e está pronta para ser utilizada como entrada na próxima etapa do processo

54 Capítulo 3. O framework Proposto 38 Figura 3.6: Visão geral da arquitetura do sistema.

55 Ambiente de Teste O componente RGB-ZProcessing é responsável por processar e manipular dados RGB-Z (vídeos RGB e mapas de profundidade filtrados). Os dados de saída em forma de texturas do componente anterior DepthProcessing, armazenadas na GPU, são utilizados para aplicar os processos de efeitos especiais, também na GPU, usando um Program Shader para cada um deles. Este componente é responsável pela estilização dos vídeos, por exemplo, da aplicação do efeito Cartoon Shading. O componente View permite visualizar um vídeo RGB-Z com algum efeito especial capturado pelo RGB-ZProcessing. Esse componente utiliza a interface provida pelo QGLWidget, que é uma classe do Qt que proporciona suporte para rendering de gráficos OpenGL [12]. Essa classe, por sua vez, se comunica com componentes da UI através do conector signal and slot, também do Qt. Um signal é emitido quando um evento associado a algum objeto emissor é acionado, por exemplo, quando um botão na UI é pressionado e liberado. Um slot, por sua vez, é um método de um objeto receptor que é chamado em resposta a um signal particular. 3.4 Ambiente de Teste Esta seção descreve o ambiente computacional e os requisitos do framework. Neste trabalho desenvolvemos a aplicação no framework Qt usando o IDE Qt Creator (Figura 3.7), a API gráfica de OpenGL e C++ como linguagem de programação. A aplicação foi desenvolvida no sistema operacional Ubuntu LTS. Os testes também foram feitos neste sistema operacional. Isto não exclui que a aplicação seja multi-plataforma, já que seus componentes são compatíveis em qualquer plataforma. O código na GPU foi desenvolvido em GLSL e testado com a placa gráfica NVIDIA GeForce GT 540M de arquitetura Fermi GF108. A Tabela 3.1 sumariza as principais características da GPU, da CPU e da câmera. As bibliotecas e ferramentas necessárias para o framework são listadas na Tabela 3.2 com suas respectivas versões.

56 Capítulo 3. O framework Proposto 40 Tabela 3.1: Especificações técnicas do hardware. Hardware Componente Especificação Técnica Câmera Dispositivo Kinect XBOX 360 CPU Processador Intel Core i5-2430m, 2.4 GHz x 4 Memória 4GB de memória RAM GPU Placa Gráfica NVIDIA GeForce GT 540M OpenGL Renderer GeForce GT 540M/PCIe/SSE2 OpenGL 4.3 GLSL Version 4.3 NVIDIA via Cg compiler Shader 5.0 Memória 1024 MB de memória RAM Shader Processors 96 Figura 3.7: O framework Qt utilizado como suporte para o desenvolvimento do sistema.

57 Ambiente de Teste Tabela 3.2: Bibliotecas e Ferramentas do framework com suas respectivas versões. Bibliotecas/Ferramentas Versão Qt Framework IDE Qt Creator PCL 1.6 OpenCV OpenNI Glew Boost 1.48 Flann Eigen 3.0.5

58

59 Capítulo 4 Desenvolvimento do Framework O objetivo da criação do framework é construir um sistema computacional capaz de atender as necessidades exigidas para o processamento de vídeos RGB-Z, assim como desenvolver componentes reutilizáveis do sistema. Uma das grandes vantagens do desenvolvimento de software baseado em uma arquitetura é a possibilidade da criação de um esqueleto para o sistema, a fim de estender cada um de seus componentes. A aplicação está em conformidade com a arquitetura projetada na Seção 3.3. Outro ponto importante que diz respeito ao desenvolvimento do projeto é a integração do Kinect com as bibliotecas e ferramentas usadas neste trabalho (Seção 3.4). A integração destes componentes (com a definição de um conjunto de processos e funções) está apoiada no propósito do processamento de vídeo RGB-Z, no qual, todos eles se complementam e criam um ambiente de execução apropriado para o sistema, ao mesmo tempo que mantém o processamento em tempo real. Portanto, o projeto envolve o estudo de conceitos específicos de processamento de imagens como preenchimento multirresolução de buracos, filtragem espaçotemporal e efeito não-fotorrealístico, bem como o estudo de métodos de programação que fornecem suporte para aplicações na GPU. O desenvolvimento do framework abrange as etapas do pipeline indicado na Figura 2.1.

60 Capítulo 4. Desenvolvimento do Framework Descrição de Classes e Funções As classes e funções são representadas no diagrama de interação mostrado na Figura 4.1. MainWindow É a classe responsável pela inicialização do sistema. Ela serve como ponte entre a interface gráfica e as classes principais do sistema. Esta classe inicializa e executa o processo de aquisição de dados do Kinect. Em seguida, envia esses dados para serem processados em uma classe com suporte de funcionalidades OpenGL (para cada janela da interface gráfica como ilustrado na Figura 5.1). MainWindow aplica as seguintes funções: OpenNIGrabber(): Instancia o objeto grabber da classe PCL:OpenNIGrabber com os parâmetros deviceid que é o identificador de dispositivo. modei e moded são os modos de captura dos dados de imagem e profundidade, respectivamente; OpenNIViewer(): Instancia o objeto onv_rgba da classe OpenNIViewer com o parâmetro grabber, que é o gravador configurado para capturar e armazenar os dados da cena; Thread(): Pertence a classe boost::thread() que herda as propriedades de uma linha de execução. Nela é atribuído o parâmetro função onv_rgba::run() que captura e armazena os dados em background; setdataonv_rgba(): Envia os dados obtidos em onv_rgba para a classe KinectView onde serão processadas. Os dados enviados como parâmetros são ptspcl (nuvem de pontos com propriedades de cor e de profundidade para cada ponto da cena), rgbimg (a imagem de cor) e depthimg (a imagem de profundidade); setnumwidgetview(): Envia para a classe KinectView o parâmetro numwidget, que é o número de janela (widget) da interface gráfica onde serão apresentados os processamentos sobre os dados.

61 Descrição de Classes e Funções :GUI :MainWindow :PCL::OpenNiGrabber :OpenNiViewer :KinectView :HandleMethod 1: OpenNiGrabber(deviceID, modei, moded) grabber Fwk::User 2: OpenNiViewer(grabber) onv_rgba 3: Thread(onv_rgba::run) 4: setdataonv_rgba(ptspcl, rgbimg, depthimg) 5: setnumwidgetview(numwidget) 6: setmethod(typemethod) 10: InitMethod(typeMethod, paramconfig) 7: createshaders() 8: createvbos() 9: createtextureoutput() 11: setdataonv_rbga(ptspcl, rgbimg, depthimg) 12: ApplyMethod() 13: gettextureoutputmethod() TextureOutput 14: DrawGL(TextureOutput) DisplayGraphicsWidget(numWidget) Figura 4.1: Diagrama de interação da visualização de um método do framework.

62 Capítulo 4. Desenvolvimento do Framework 46 PCL::OpenNIGrabber É uma classe da biblioteca PCL. Fornece uma interface de captura genérica para um acesso fácil e conveniente para diferentes dispositivos e seus drivers. OpenNIViewer É a classe que inicializa a conexão do grabber com o dispositivo usando funções callback para cada tipo de dados a serem obtidos, e, posteriormente executa o registro deles. Assim, fornece dados da imagem de cor (tipo boost::shared_ptr<openni_wrapper ::Image>), com um formato de 32 bits, sendo 8 bits para cada canal, e de profundidade (tipo boost:: shared_ptr<openni_wrapper::depthimage>), com um formato de 16 bits para um canal em ponto flutuante. Esses dados são obtidos em arranjos que são transformados em imagens (tipo IplImage), usando a biblioteca OpenCV. O grabber também proporciona dados no espaço 3D como nuvem de pontos (tipo pcl::pointcloud<pcl::pointxyzrgba>:: ConstPtr), onde cada ponto da profundidade está alinhado à sua respectiva cor. KinectView É uma extensão da classe QGLWidget que proporciona suporte para rendering de gráficos OpenGL. QGLWidget fornece métodos virtuais que devem ser implementadas para executar tarefas OpenGL comuns. Três deles são os mais utilizados e implementados na aplicação: initializegl(), resizegl() e paintgl(). initializegl() é chamado sempre que o widget é atribuído a um novo contexto OpenGL. Destina-se a conter o código de inicialização OpenGL que vem antes da primeira chamada para os outros métodos. resizegl() manipula o redimensionamento da janela OpenGL. paintgl() aplica o rendering da cena OpenGL sempre que o widget precisa ser redesenhado. Ele é atualizado em cada intervalo de tempo. Antes de fazer rendering a classe recebe o typemethod, tipo de método a ser processado, e os dados obtidos do Kinect prontos para serem usados. Assim temos: InitMethod(): Inicializa um dos métodos que pertencem à classe HandleMethod. Para isso, envia o parâmetro typemethod e os dados de configuração do método envolvidos no parâmetro paramconfig;

63 Descrição de Classes e Funções SetDataONV_Rgba(): Envia para a classe HandleMethod os dados da cena que o método precisa. Esses são ptspcl (nuvem de pontos), rgbimg (imagem de cor) e depthimg (imagem de profundidade). Os dados são enviados em cada intervalo de tempo; ApplyMethod(): Aplica o método escolhido no processamento. Cada método pertence a classe HandleMethod. Nesta função, cada método está habilitado para executar o renderto-texture; gettexturaoutputmethod(): Com este método a classe KinectView obtém a textura de saída da função anterior; DrawGL(): Em cada intervalo de tempo, esta função aplica o rendering final para que a cena seja exibida na tela. As tarefas OpenGL necessárias para o rendering (rendering-to-texture ou rendering na tela) são mostradas na Listagem 4.28 na seguinte ordem: Transformações model-view: Qt fornece um conjunto de classes de vetores e matrizes para trabalhar com transformações geométricas e configurações da câmera. Na classe KinectView declaramos dois objetos tipo QMatrix4x4. Eles são modelviewmatrix e ProjectionMatrix. Primeiro cada objeto matriz é inicializado para a matriz identidade. Em seguida, à direita, multiplica-se pela matriz correspondente a um método específico. Os métodos de ProjectionMatrix indicam o tipo de projeção na tela. Os métodos de modelviewmatrix criam uma matriz de visualização, além de aplicar transformações geométricas (rotação, translação e escala); Binding [41] do programa shader: tarefa do tipo QGLShaderProgram; Carregamento dos dados uniform para a GPU: o conteúdo das estruturas definidas (vetores e matrizes) na CPU podem ser vinculadas a atributos do shader utilizando métodos da classe QGLShaderProgram, declarados como tipos de dados nativos vec2, vec3, vec4, mat2, mat3, mat4. (Listagem 4.24, Linhas 7 e 8);

64 Capítulo 4. Desenvolvimento do Framework 48 Binding dos objetos buffer e texturas para a GPU: a textura é atribuída a uma variável shader, que pode ser do tipo sampler2d ou, como o exemplo samplerbuffer (Listagem 4.24 na Linha 10) onde passamos dados usando TBO, segundo a unidade de textura correspondente. Finalmente, vinculamos a textura ao shader passando como parâmetro o identificador de textura que lhe foi atribuído quando criada. Cada objeto buffer VBO é igualmente vinculado e, atribui-se a eles os atributos correspondentes do programa shader. Após isso, chama-se o comando nativo OpenGL adequado (gldrawelements() ou gldrawarrays()) para desenhar a malha ou textura; Liberação dos buffer objects e shader programs: o método DrawGL() é encerrado. O framework Qt também fornece métodos virtuais na classe QGLWidget que são chamados em resposta a eventos do mouse. Esses métodos manipulam um trackball virtual definido na classe Trackball [12] e uma mudança de escala. Para que isso seja posível, a classe KinectView implementa os métodos mousemove(), mousepress(), mouserelease() e wheelevent(). HandleMethod É a classe que representa cada método no processamento de vídeos RGB-Z. A classe define as estruturas e o programa shader para cada método específico. A classe recebe os dados prontos do Kinect através da classe Kinectview. HandleMethod aplica as seguintes funções: CreateVBOs(): permite definir objetos buffer exigidos pelo método, como mostrado na Listagem O conceito de VBO permite a manipulação de atributos dos vértices na GPU tais como posição, normais, texturas, cores, índices, etc. O Qt fornece a classe QOpenGLBuffer para lidar com objetos buffer; CreateShaders(): permite definir o programa shader exigido pelo método. O Qt fornece a classe QGLShaderProgram para manipulá-lo. Essa classe provê métodos para compilar o código fonte em GLSL como um tipo específico da classe QGLShader (Vertex,

65 Descrição de Classes e Funções Geometry e Fragment) e adiciona-lo para esse programa shader, como mostrado na Listagem 4.1, Linhas 1 à 20; CreateTextureOutput(): executa duas sub-funções, a criação de texturas e de objetos FBO (mostrados na Listagem 4.1). Para criar uma textura definimos três características principais: tipo (por exemplo GL_TEXTURE_2D), tamanho (por exemplo ) e formato (por exemplo GL_RGBA). Uma textura pode ser utilizada de duas maneiras, como entrada ou saída no rendering de um programa shader. Quando a saída do rendering é em uma textura (ou seja fora da tela), o método é conhecido como render-to-texture e precisa definir um objeto FBO. O FBO permite ao usuário criar um framebuffer para fazer rendering fora da tela. As duas sub-funções retornam um identificador com os quais são vinculadas a um shader na aplicação do método. Quando a classe Kinectview executa a função ApplyMethod(), está sendo aplicado um método que, por sua vez, pode executar outros sub-métodos. Isso depende do tipo de método. Esses sub-métodos também pertencem à mesma classe HandleMethod. GUI Representa a interface gráfica do usuário. Ela possui um ou vários widgets fornecidos pela classe QGLWidget. Cada widget é exibido em uma janela na tela contendo o rendering final da classe Kinectview. Neste caso, representado pelo método DisplayGraphicsWidget segundo o número de janela refletido no parâmetro numwidget. User Representa o usuário que pode escolher o método a ser aplicado. Esta operação é feita através de mecanismos signal/slots do framework Qt, que intercomunicam componentes da UI com a classe Kinectview. O usuário aplica a função slot setmethod(), introduzindo o parâmetro typemethod, em resposta a um signal particular quando pressiona e libera um botão na UI.

66 Capítulo 4. Desenvolvimento do Framework Relações das Classe nos Processos do Framework Em seguida serão descritas as relações das classes nos processos do framework. Captura dos dados Este processo tem a tarefa de capturar os dados do Kinect. A classe Mainwindow é responsável pela inicialização, configuração e execução dessa tarefa. Ela define uma interface de suporte para a captura usando a classe PCL::OpenNIGrabber. Em seguida, inicia-se a conexão e o registro dos dados usando a classe OpenNIViewer. O registro é executado em background em uma linha de execução pertencente à classe Thread. Assim, os dados do Kinect estão prontos para serem processados, como imagem de cor, imagem de profundidade e mapa de profundidade. Logo, os dados são passados para a classe kinectview onde é aplicado o rendering de cada um deles. Finalmente, a saída é exibida na tela usando a classe GUI. Preenchimento em multirresolução Este processo tem a tarefa de preencher regiões sem informação do mapa de profundidade. O processo segue os passos que foram explicados na Seção 2.2. A classe User faz o pedido da aplicação do processo, enviando o tipo de método para a classe kinectview. Esta classe chama o método Fill_In da classe HandleMethod enviando os parâmetros de configuração dos dados do Kinect. Esse método utiliza outros submétodos que pertencem à mesma classe HandleMethod. São eles, Sobel, Downsampling, Upsampling e CrossBilateralFilter. Em primeiro lugar, o método Fill_In cria estruturas e shaders. Em seguida, aplica o método Sobel, cuja saída é uma textura. Após isso, segundo o algoritmo de preenchimento em multirresolução, o método Downsampling é primeiramente aplicado nas texturas do Sobel e da imagem de cor e, suas saídas servem para aplicar o método de forma iterativa (de acordo com o número de níveis de resolução que é passado como parâmetro). O próximo passo é a aplicação dos métodos Upsampling e CrossBilateralFilter sobre as texturas resultantes do método Downsampling em cada nível. A saída final é uma textura que retorna à classe kinectview para fazer o rendering na

67 Interação dos Shaders tela usando a classe GUI. Filtro espaço-temporal Este processo tem a tarefa de filtrar o mapa de profundidade nas dimensões de espaço e tempo. Depois da classe User fazer o pedido para aplicar esse processo, a classe Kinectview chama o método SpatioTemporalFilter. Em seguida envia-lhe parâmetros e dados respectivos. Esse método invoca os sub-métodos Fill_In e OpticalFlow. Primeiramente, o método Fill_In é aplicado como foi descrito no processo anterior. Logo após, aplica o método OpticalFlow utilizando como dados as texturas da imagem de cor, do frame atual bem como do frame anterior. Tanto as texturas resultantes desses métodos quanto as texturas da imagem de cor, do frame atual e do frame anterior, são dados usados para aplicar o método SpatioTemporalFilter, adicionando, como um dado a mais seu resultado a partir do segundo intervalo de tempo da execução do método (ou seja, o método utiliza cinco texturas como entradas). Finalmente, como todo método que pertence à classe HandleMethod, a textura de saída é enviada para a classe Kinectview, a qual faz rendering dela na tela usando a classe GUI. Efeitos sobre os vídeos Este processo tem a tarefa de aplicar um efeito especial em uma imagem ou em uma malha. Da maneira semelhante aos processos anteriores, as classes User, Kinectview e GUI desempenham o mesmo papel. Aqui é chamado o método Efeito que, por sua vez, invoca o sub-método SpatioTemporalFilter. A textura resultante desse submétodo é usada para extrair a informação exata da profundidade da cena, a fim de executar um efeito especial específico na imagem de cor ou na malha. 4.3 Interação dos Shaders No desenvolvimento do presente trabalho, todos os algoritmos de processamento e de rendering são executados na GPU por meio de programas shaders. Como dito anteriormente, na Seção 3.1, os shaders são arquivos de texto encapsulados em programas shaders em uma apli-

68 Capítulo 4. Desenvolvimento do Framework 52 cação na CPU, tornando possível a leitura, compilação, link e execução dos mesmos na GPU. Em relação aos processos definidos na seção anterior, apresentamos na Figura 4.2 a interação dos shaders representada em um fluxograma. Ele nos dá uma visão geral de como os shaders estão conectados com relação à entrada e saída de dados em cada método. O fluxograma mostra de modo claro quais são os dados de entrada e saída de um método. Igualmente mostra os arquivos shaders usados em cada método. De maneira simplificada, a linha vertical tracejada separa as principais funcionalidades da CPU e GPU no sistema. Na CPU os dados são capturados, preparados e enviados para GPU. A GPU recebe esses dados e os processa de acordo com o método. A saída de cada método é armazenada na memória da GPU e, em seguida, convertida em dado de entrada para outro método na mesma GPU. O resultado é então mostrado na tela. O bloco (A) do fluxograma reúne todos os métodos utilizados no processo de preenchimento. O processo tem dois níveis de sub-resolução. Para cada nível de resolução são aplicados os métodos Upsampling e CrossBilateralFilter segundo o Algoritmo 1. O bloco (B) reúne os métodos para o processo de filtragem. O dado PreviousColor é a textura da imagem de cor do frame no intervalo de tempo prévio. O dado PreviousSTDepth é a saída do método SpatioTemporalFilter aplicado no frame do intervalo de tempo anterior. O bloco (C) aplica apenas um método para o processo de efeito especial. Com o objetivo de representar o uso de texturas como dados de entrada ou de saída de um método, o fluxograma da Figura 4.3 mostra um fluxo padrão para todos os métodos em relação ao uso dessas texturas. Na aplicação na CPU, o processo de criação de textura retorna um identificador de textura, que é utilizado para ser enlaçado com um FBO (que permite fazer render-to-texture). Em seguida é aplicado o método na GPU. A textura resultante é armazenada na memória dela, pronta para ser utilizada por qualquer outro método. Assim, por exemplo para exibir a textura na tela, é necessário enviar como dado de entrada o identificador dessa textura para a GPU no programa shader que realizará o rendering. Por outro lado, o Framework oferece também tipos diferentes de visualização dos dados.

69 Interação dos Shaders CPU GPU Begin Kinect Color Depth Sobel: A vsobel.glsl fsobel.glsl DepthSobel DownSampling 1: DownDepth 1 DownSampling 2: DownDepth 2 vposvertices.glsl fdownsampled.glsl DownColor 1 vposvertices.glsl fdownsampled.glsl DownColor 2 Cross Bilateral Filter: vposvertices.glsl fcrossbilateralfilter.glsl CBDepth 1 Cross Bilateral Filter 1: vposvertices.glsl fcrossbilateralfilter.glsl Cross Bilateral Filter 2: vposvertices.glsl fcrossbilateralfilter.glsl UpDepth UpSampling: vposvertices.glsl fupsampled.glsl UpDepth 1 UpSampling 1: vposvertices.glsl fupsampled.glsl CBDepth 2 Previous Color Optical Flow: CBDepth Spatio Temporal Filter: B vposvertices.glsl Rgb2gray.glsl Linear1D5Filter.glsl Reduce.glsl Derivates1D5.glsl SecondDerivates1D5.glsl CalculateTensor.glsl Phi3.glsl JacobiAndUpdateUV.glsl Scale.glsl ScaleToResult.glsl OFImage vposvertices.glsl fspatiotemporalfilter.glsl STDepth Previous STDepth Effect Image: C Display EffectImage veffectcolormap.glsl fcartoonshadingcolormap.glsl End Figura 4.2: Interação dos shaders, mostra entradas e saídas de dados para cada método das fases no todo o processamento. Cada fase é representada em blocos, A: preenchimento, B: filtragem e C: efeito especial. Cada método contém os arquivos shader em GLSL.

70 Capítulo 4. Desenvolvimento do Framework 54 CPU GPU Begin Create Texture IDTexture Create FBO and bind to Texture Applying the Method Method Program Shader Rendering to Texture Display Method? Memory GPU No Yes Binding IDTexture Rendering Program Shader Texture End Display Figura 4.3: Fluxograma do rendering de um método: rendering-to-texture ou rendering na tela. Elas estão implementadas em shaders de acordo com as características que apresentam, ou seja, dependendo se os dados são originais do Kinect (com ruído e buracos) ou processados (filtrados). Os seguintes fluxogramas representam três métodos de visualização, como nuvem de pontos, malha como wireframe e superfície da malha com aplicação da iluminação. Para cada um desses métodos são considerados dados de entrada e programa shader específicos. No caso de visualizar os dados filtrados é preciso mudar apenas o Vertex Shader em relação aos dados originais. Em particular, para fazer rendering de uma nuvem de pontos, o fluxograma da Figura 4.4-a apresenta o caso com dados originais do Kinect, no qual destacam vértices e cores encapsulados em objetos VBO (vbovertex e vbocolor, respectivamente). Devido à natureza

71 Interação dos Shaders CPU GPU CPU GPU Begin Begin Memory GPU vbovertex Color Texture vbocolors Others Raw Point Cloud Program Shader: vpointcloudcol.glsl fpointcloudcol.glsl vbotexcoords vbovertex Others STDepth Texture Full Point Cloud Program Shader: vpointclouddepthfilt.glsl fpointcloudcol.glsl End Display End Display (a) (b) Figura 4.4: Fluxograma de visualização da nuvem de pontos. Em (a) dados originais e em (b) dados filtrados. dos dados, nem todos os pontos contêm profundidade e cor. Já no segundo caso, mostrado na Figura 4.4-b, a profundidade de todos os pontos é atualizada com o mapa de profundidade filtrado e armazenado na memória da GPU (textura STDepth). A textura Color é enviada para GPU, a qual obtém a cor de cada ponto. As coordenadas de textura, encapsuladas em um VBO (vbotexcoord), trabalham com as localizações dos pontos nas texturas na GPU. Além desses dados, são enviados dados de projeção e transformações de coordenadas, representado no dado Others. O programa shader é composto por Vertex e Fragment Shader. Para a visualização da malha como wireframe, a Figura 4.5-a mostra no caso de visualizar os dados originais são enviados para a GPU, além dos vértices, os índices encapsulados em um VBO (vboindex). Os índices indicam como estão distribuídos os vértices para formar uma face de um objeto, neste caso a cena capturada. A Figura 4.7 mostra a malha formada por faces triangulares. Para os dados filtrados, a Figura 4.5-b mostra, como entradas, os mesmos índices além de vbovertex, vbotexcoord, STDepth e Others, utilizados do mesmo modo que na visualização de nuvem de pontos com dados filtrados. O programa shader para conseguir o wireframe é composto por Vertex, Geometry e Fragment Shader.

72 Capítulo 4. Desenvolvimento do Framework 56 CPU GPU CPU GPU Begin Begin Memory GPU vbovertex vboindex vboindex Others Raw Wireframe Program Shader: vwireframe.glsl gwireframe.glsl fwireframe.glsl vbotexcoords vbovertex Others STDepth Texture Full Wireframe Program Shader: vwireframedepthfilt.glsl gwireframe.glsl fwireframe.glsl End Display End Display (a) (b) Figura 4.5: Fluxograma de visualização da malha como wireframe. Em (a) dados originais e em (b) dados filtrados. CPU GPU CPU GPU Begin Begin Memory GPU vbovertex vboindex vboindex vbotexcoords STDepth Texture vbotexcoords vbovertex Full Phong Program Shader: TBO Others Raw Phong Program Shader: vphong.glsl gphong.glsl fphong.glsl Others vphongdepthfilt.glsl gphong.glsl fphong.glsl End Display End Display (a) (b) Figura 4.6: Fluxograma de visualização da superfície da malha com aplicação de iluminação. Em (a) dados originais e em (b) dados filtrados. Finalmente, visualiza-se a superfície da malha com aplicação da iluminação de Phong (descrita na Seção 4.4.4). No caso dos dados originais, a Figura 4.6-a mostra que, além de vértices e índices (como no método anterior), é enviada para GPU a estrutura TBO. Ele armazena os

73 Implementação de Shaders em GLSL dados de profundidade em forma de uma textura unidimensional com a finalidade de calcular as normais de cada vértice na GPU. Para isto, é preciso definir coordenadas de textura em vbotexcoord. Em Others é adicionado dados da luz (posição, direção, cor, propriedades) e a matriz inversa da matriz de transformações de coordenadas, que será aplicada para transformar as normais dos vértices nas coordenadas de olho (sistema de coordenadas do olho, ou da câmera, é aquele em que todos os objetos da cena serão desenhados). A Figura 4.6-b mostra a variação que, ao invés de usar TBO para encontrar as normais na GPU, utiliza a textura STDepth armazenada na memória da GPU. Todos os outros dados de entrada são utilizados da mesma forma que no método anterior. Aqui, também, o programa shader é composto por Vertex, Geometry e Fragment Shader. 4.4 Implementação de Shaders em GLSL Nesta seção são descritos detalhes técnicos da implementação do Framework. Os shaders usados para o processamento de vídeo RGB-Z e sua interação são mostrados no fluxograma da Figura 4.2. No caso dos processos de preenchimento e filtragem, foram adaptados os shaders implementados por Richardt et al. [36], de acordo com o objetivo do presente trabalho. Além disso, os shaders para o fluxo óptico são implementados conforme o trabalho de Eisemann et al. [8]. A implementação de cada processo ocorre conforme a descrição apresentada na Seção Shaders do Preenchimento em Multirresolução O método de Preenchimento em Multirresolução é denominado Fill_In, ele pertence à classe HandleMethod e utiliza os sub-métodos Sobel, Downsampling, Upsampling e CrossBilateralFilter. Como é representado na Figura 4.1, todos os métodos criam objetos FBO, texturas e shaders com um formato padrão. Um exemplo de todos eles é mostrado na Listagem 4.1.

74 Capítulo 4. Desenvolvimento do Framework 58 1 GLboolean Fill_In:: CreateShaders( QGLShaderProgram * shaderp, const QString& vertpath, const QString& fragpath, const QString& geompath ) 2 { 3 bool result; 4 5 result=shaderp ->addshaderfromsourcefile( vertpath); 6 if (! result) qwarning() << shaderp ->log(); 7 result=shaderp ->addshaderfromsourcefile( fragpath); 8 if (! result) qwarning() << shaderp ->log(); 9 if ( geometryshaderpath!= "") 10 { 11 result=shaderp ->addshaderfromsourcefile( geompath); 12 if (! result ) qwarning() << shaderp ->log(); 13 } 14 result=shaderp ->link(); 15 if (! result) qwarning() <<" Could not link shader program:" <<shaderp ->log(); 16 return result; 17 } GLuint Fill_In:: CreateTextureDataf( GLuint w, GLuint h) 20 { 21 GLuint texid = 0; 22 glgentextures(1, & texid); 23 glbindtexture( GL_TEXTURE_2D, texid); 24 glteximage2d( GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_FLOAT, 0); 25 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 26 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 27 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 28 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 29 glbindtexture( GL_TEXTURE_2D,0); return texid; 32 } GLuint Fill_In:: CreateFBO( GLuint texids) 35 { 36 GLuint fboid = 0; 37 glgenframebuffers(1, & fboid); 38 glbindframebuffer( GL_FRAMEBUFFER, fboid); 39 GLenum Db[1] = { GL_COLOR_ATTACHMENT0}; 40 glframebuffertexture2d( GL_FRAMEBUFFER,Db[0], GL_TEXTURE_2D, texids,0); 41 gldrawbuffers(1, DrawBuffers); // "1" is the size of DrawBuffers 42 // Always check that our framebuffer is ok 43 if( glcheckframebufferstatus( GL_FRAMEBUFFER)!= GL_FRAMEBUFFER_COMPLETE) 44 std:: cout <<" GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO"; return fboid; 47 } Listagem 4.1: Fill_In.cpp: métodos CreateShaders(), CreateTextureDataf() e CreateFBO().

75 Implementação de Shaders em GLSL Também na Listagem 4.2 temos a criação de estruturas VBO para o método Sobel. Esse método é o que inicia o processamento sobre os dados da profundidade da cena. Ele é aplicado com a função ApplySobel(), que é uma extensão do método paintgl. Aqui, todos os objetos criados, VBO e shaders, são enlaçados à GPU para fazer, neste caso, o render-to texture definido na Listagem 4.3. Na função ApplySobel(), a profundidade é enviada em duas texturas. A primeira com valores RGB entre 0 e 1 (Linha 18), que representam valores de cor, e a segunda com os valores RGB reais da profundidade (Linha 20). 1 void Sobel:: createvbos() 2 { 3 glgenvertexarrays(1, & VAO); 4 glbindvertexarray( VAO); 5 6 numvertices = 480*640; 7 indices = new unsigned int[ numvertices]; 8 vertices = new QVector4D[ numvertices]; 9 texcoords = new QVector2D[ numvertices]; 10 int k = 0; for ( unsigned int i = 0; i < 480; i++) 13 for ( unsigned int j = 0; j < 640; j++) 14 { 15 indices[k] = k; 16 vertices[k] = QVector4D(j,i,0,1.0); 17 texcoords[k] = QVector2D(j,i); 18 k++; 19 } vbovertices = createobjetobuffer( QOpenGLBuffer:: VertexBuffer, 22 QOpenGLBuffer:: DynamicDraw, vertices, numvertices* sizeof( QVector4D)); 23 deletevector( vertices); vbotexcoords = createobjetobuffer( QOpenGLBuffer:: VertexBuffer, 26 QOpenGLBuffer:: StaticDraw, texcoords, numvertices* sizeof( QVector2D)); 27 deletevector( texcoords); vboindices = createobjetobuffer( QOpenGLBuffer:: IndexBuffer, 30 QOpenGLBuffer:: StaticDraw, indices, numvertices* sizeof( unsigned int)); 31 deletevector( indices); glbindvertexarray (0); 34 } Listagem 4.2: Sobel.cpp: método CreateVBOs().

76 Capítulo 4. Desenvolvimento do Framework 60 As Listagem 4.4 e 4.5 mostram como os dados são convertidos às texturas de imagem e de profundidade, respectivamente. 1 void Sobel:: ApplySobel() 2 { 3 glbindframebuffer( GL_FRAMEBUFFER, FBOSobel); 4 5 modelviewmatrix. settoidentity(); 6 projectionmatrix. settoidentity(); 7 projectionmatrix. ortho(0, 640,480, 0, -1.0f, 1.0f); 8 if (! SobelShaderProgram ->bind() ) 9 { 10 qwarning() << " Could not bind shader program to context"; return; 11 } 12 SobelShaderProgram ->setuniformvalue(" modelviewmatrix", modelviewmatrix); 13 SobelShaderProgram ->setuniformvalue(" projectionmatrix", projectionmatrix); 14 SobelShaderProgram ->setuniformvalue(" texdepthmap", 0); 15 SobelShaderProgram ->setuniformvalue(" texdepth", 1); 16 SobelShaderProgram ->setuniformvalue(" sobelthreshold", 0.10f); 17 glactivetexture( GL_TEXTURE0); 18 _teximg = createtextureimage( depthimg, context(),_teximg); 19 glactivetexture( GL_TEXTURE1); 20 _textura = SetTexturaDepth(); 21 glbindtexture( GL_TEXTURE_2D, _textura); vbovertices ->bind(); 24 SobelShaderProgram ->setattributebuffer(" vposition", GL_FLOAT, 0, 4); 25 SobelShaderProgram ->enableattributearray(" vposition"); 26 vbotexcoords ->bind(); 27 SobelShaderProgram ->setattributebuffer(" vtexcoord", GL_FLOAT, 0, 2); 28 SobelShaderProgram ->enableattributearray(" vtexcoord"); 29 vboindices ->bind(); 30 gldrawelements( GL_POINTS, numvertices, GL_UNSIGNED_INT, 0); vboindices ->release(); 33 vbotexcoords ->release(); 34 vbovertices ->release(); 35 SobelShaderProgram ->release(); 36 } Listagem 4.3: Sobel.cpp: método ApplySobel().

77 Implementação de Shaders em GLSL 1 GLuint Sobel:: createtextureimage( IplImage * img, QGLContext * glcontext, GLuint teximage) 2 { 3 GLuint teximg = 0; 4 QImage mimage; 5 6 if( img ->nchannels == 3) 7 mimage = QImage(( const unsigned char*)(img ->imagedata), img ->width, 8 img ->height,img ->widthstep/ sizeof( uchar),qimage:: Format_RGB888); 9 10 else if( img ->nchannels == 1) 11 mimage = QImage(( const unsigned char*)(img ->imagedata), img ->width, 12 img ->height,img ->widthstep/ sizeof( uchar), QImage:: Format_Indexed8); else 15 return 0; mimage = QGLWidget:: converttoglformat( mimage); if( teximage > 0) 20 glcontext ->deletetexture( teximage); teximg = glcontext ->bindtexture( mimage); 23 gltexparameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 24 gltexparameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); return teximg; 27 } Listagem 4.4: Sobel.cpp: método CreateTextureImage(). 1 GLuint Sobel:: CreateTexturaDepth() 2 { 3 float * vert = new float [640*480]; 4 int k = 0, p = 0; 5 for ( int i = 479; i >-1; i--) 6 { 7 for ( unsigned int j = 0; j < 640; j++) 8 { 9 k = i*640+j; 10 float value = cloud ->points.at(k).z; 11 if( isnan( value) ) value = 0.0; 12 vert[p*640+j] = value; 13 } 14 p++; 15 } 16 if(_textura > 0) 17 { 18 deletetexture(_textura); _textura = 0; 19 } 20 _textura = settexturedatafdepth(640, 480, vert); 21 return _textura; 22 }

78 Capítulo 4. Desenvolvimento do Framework GLuint Sobel:: SetTextureDatafDepth( GLuint w, GLuint h, float * data) 25 { 26 GLuint texid = 0; 27 glgentextures(1, & texid); 28 glbindtexture( GL_TEXTURE_2D, texid); glteximage2d( GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data); 31 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 32 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 33 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 34 gltexparameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); return texid; 37 } Listagem 4.5: Sobel.cpp: método CreateTextureDepth e SetTextureDatafDepth(). O Vertex Shader para o Sobel (Listagem 4.6) recebe os dados da CPU e para cada vértice faz o cálculo da seu gradiente na função getsobel (Linha 22), que chamaremos de valor sobel, como foi explicado na Seção 2.2. A cor para cada vértice é obtida da textura da imagem chamada texdepthmap (Linha 38) e a profundidade é obtida da textura de profundidade chamada texdepth, que logo é armazenada na propriedade a do vértice (Linha 39). O Fragment Shader (Listagem 4.7) recebe a cor correspondente para cada pixel além do valor sobel, o qual é avaliado para encontrar a borda da profundidade; os pixels com valor sobel maiores ao valor de limiarização são bordas e são invalidados (Linha 12). Quando o método Fill_In é aplicado, ele executa todos os sub-métodos correspondentes ao processo de preenchimento. A Listagem 4.8 mostra a entrada e saída de texturas na função ApplyFillIn(), conforme a interação dos shaders exibidos na Figura 4.2-A. A Listagem 4.9 mostra o shader para o método Downsampling, a Listagem 4.10 mostra o shader para o método Upsampling. Por último, a Listagem 4.11 mostra o shader para o método CrossBilateralFilter.

79 Implementação de Shaders em GLSL 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 uniform mat4 modelviewmatrix; 4 uniform mat4 projectionmatrix; 5 uniform sampler2d texdepthmap; 6 uniform sampler2d texdepth; 7 8 out float sobel; 9 out vec4 color; // returns the coordinates of the current vertex 12 vec3 getvertex( sampler2d coordinates, vec2 position) 13 { 14 // texel coordinate from texture coordinate 15 ivec2 texelpos = ivec2( position); 16 // clamp texel coordinate to valid range 17 texelpos=clamp( texelpos, ivec2(0), texturesize( coordinates,0)-ivec2(1)); 18 // fetch vertex coordinates, in world coordinates 19 return texelfetch( coordinates, texelpos, 0). xyz; 20 } float getsobel() 23 { 24 float[9] z; 25 vec3 vertexcoord = getvertex( texdepth, vtexcoord); 26 // look up depth of the 8 neighbours 27 vec2 tsize = vec2(1) / texturesize2d( texdepth, 0); 28 z[0] = texture2d( texdepth, ( vtexcoord.xy + vec2(-1.0, -1.0)) * tsize).x; 29 z[1] = texture2d( texdepth, ( vtexcoord.xy + vec2( 0.0, -1.0)) * tsize).x; 30 z[2] = texture2d( texdepth, ( vtexcoord.xy + vec2( 1.0, -1.0)) * tsize).x; 31 z[3] = texture2d( texdepth, ( vtexcoord.xy + vec2(-1.0, 0.0)) * tsize).x; 32 z[4] = vertexcoord.x; 33 z[5] = texture2d( texdepth, ( vtexcoord.xy + vec2( 1.0, 0.0)) * tsize).x; 34 z[6] = texture2d( texdepth, ( vtexcoord.xy + vec2(-1.0, 1.0)) * tsize).x; 35 z[7] = texture2d( texdepth, ( vtexcoord.xy + vec2( 0.0, 1.0)) * tsize).x; 36 z[8] = texture2d( texdepth, ( vtexcoord.xy + vec2( 1.0, 1.0)) * tsize).x; color. rgb=texture2d( texdepthmap,( vtexcoord.xy+vec2(0.0,0.0))* tsize). rgb; 39 color.a= vertexcoord.r; 40 // compute gradient magnitude 41 return sqrt( pow(z[0] + 2 * z[1] + z[2] - z[6] - 2 * z[7] - z[8], 2) + 42 pow(z[0] + 2 * z[3] + z[6] - z[2] - 2 * z[5] - z[8], 2)); 43 } void main() 46 { 47 sobel = getsobel(); 48 vec4 eyeposition = modelviewmatrix * vposition; 49 gl_position = projectionmatrix * eyeposition; 50 } Listagem 4.6: vsobel.glsl.

80 Capítulo 4. Desenvolvimento do Framework 64 1 out vec4 fragcolor; 2 3 in float sobel; 4 in vec4 color; 5 6 uniform float sobelthreshold; 7 8 void main() 9 { 10 fragcolor = color; if( sobel >sobelthreshold) 13 fragcolor = vec4(0.0,0.0,0.0,0.0); 14 } Listagem 4.7: fsobel.glsl. 1 Gluint Fill_In:: ApplyFillIn() 2 { 3 DepthSobel = applysobel(); 4 5 DownDepth1 = applydownsampled( fbodown1,320,240, DepthSobel); 6 DownColor1 = applydownsampled( fbodown2,320,240, Color); 7 DownDepth2 = applydownsampled( fbodown3,160,120, DownDepth1); 8 DownColor2 = applydownsampled( fbodown4,160,120, DownColor1); 9 10 CBDepth2 = applycrossbf( fbocb2,160,120, DownColor2, DownDepth2, DownDepth2); 11 UpDepth1 = applyupsampled( fboup1, 320, 240, CBDepth2, DownDepth1 ); 12 CBDepth1 = applycrossbf( fbocb1, 320, 240, DownColor1, UpDepth1, DownDepth1); 13 UpDepth = applyupsampled( fboup, 640, 480, CBDepth1, DepthSobel); 14 CBDepth = applyfiltrobilateral(fbocb, 640, 480, Color, UpDepth, DepthSobel); return CBDepth; 17 } Listagem 4.8: Fill_In.cpp: método ApplyFillIn().

81 Implementação de Shaders em GLSL 1 out vec4 fragcolor; 2 uniform float factor; 3 uniform sampler2d texcolormap; 4 5 void main() 6 { 7 // texel to look up 8 vec2 texel = factor * gl_fragcoord.xy ; 9 // read pixel value ( equivalent to texelfetch(input, ivec2( texel), 0)) 10 vec4 pixel= 11 texture2d( texcolormap, texel/( vec2( texturesize2d( texcolormap,0)))); 12 fragcolor = pixel; 13 } 1 out vec4 fragcolor; 2 uniform float factor; 3 uniform sampler2d texlow; 4 uniform sampler2d texhigh; 5 6 void main() 7 { Listagem 4.9: fdownsampled.glsl (Adaptado de [36]). 8 ivec2 lorestexel = ivec2( gl_fragcoord.xy) / int( factor); 9 ivec2 hirestexel = ivec2( gl_fragcoord.xy); 10 // read pixel values ( equivalent to texelfetch(..., ivec2( texel), 0)) 11 vec4 lorespixel= 12 texture2d( texlow,( vec2( lorestexel) +0.5)/( vec2( texturesize2d( texlow,0)))) ; 13 vec4 hirespixel= 14 texture2d( texhigh, gl_fragcoord.xy/( vec2( texturesize2d( texhigh,0)))); 15 // per default, use existing hi- res value 16 fragcolor = hirespixel; 17 // use new samples only in invalid areas 18 if( hirespixel.a == 0.0 && lorespixel.a!= 0.0) 19 if( hirestexel.x == factor * lorestexel.x ) 20 if( hirestexel.y == factor * lorestexel.y ) 21 fragcolor = lorespixel; 22 } 1 out vec4 fragcolor; 2 3 uniform sampler2d texcolor; 4 uniform sampler2d texpoints; 5 uniform sampler2d texrawpoints; 6 uniform float spatialsigma; 7 uniform float rangesigma; 8 9 void main() 10 { Listagem 4.10: fupsampled.glsl (Adaptado de [36]). 11 // assuming every texture has the same size

82 Capítulo 4. Desenvolvimento do Framework vec2 size = vec2( texturesize2d( texcolor, 0)); 13 // precompute 1 / sigma ^2 14 float isigmas = 1.0 / (2.0 * spatialsigma * spatialsigma); 15 float isigmar = 1.0 / (2.0 * rangesigma * rangesigma); 16 // truncate Gaussian after 2 sigma 17 int radius = int( ceil(2.0 * spatialsigma)); 18 // colour andceil coordinate at the central pixel 19 vec3 centrecolour = texture2d( texcolor, gl_fragcoord.xy / size). rgb; 20 vec4 centrepoint = texture2d( texpoints, gl_fragcoord.xy / size); 21 // determine point validity 22 validpoint = texture2d( texrawpoints, gl_fragcoord.xy / size).a; 23 // default result: unfiltered point 24 fragcolor = centrepoint; 25 // only fill in invalid pixels 26 if( validpoint == 0.0) 27 { 28 // homogeneous accumulator of depth, i.e. (wz, w) 29 vec2 acc1 = vec2(0.0); 30 vec2 acc2 = vec2(0.0); for( int dy = -radius; dy <= radius; dy++) 33 { 34 for( int dx = -radius; dx <= radius; dx++) 35 { 36 vec2 coords = ( gl_fragcoord.xy + vec2(dx, dy)) / size; 37 // colour values at the current pixel 38 vec3 currentcolour = texture2d( texcolor, coords). rgb; 39 vec4 currentpoint = texture2d( texpoints, coords); 40 // only accumulate valid points 41 if( currentpoint.a!= 0.0) 42 { 43 // compute pixel weight, using exp(a) * exp(b) = exp(a + b); 44 float w = 0.0; 45 // spatial weight 46 vec2 deltas = vec2(dx, dy); 47 w += isigmas * dot( deltas, deltas); 48 // range weight 49 vec3 deltar = currentcolour - centrecolour; 50 w += isigmar * dot( deltar, deltar); acc1 = ( exp(-w) * vec2( currentpoint.r, 1.0)) + acc1; 53 acc2 = ( exp(-w) * vec2( currentpoint.a, 1.0)) + acc2; 54 } 55 } 56 } 57 if( acc1.y > 0.0) 58 fragcolor = vec4( acc1. xxx / acc1.yyy, acc2.x / acc2.y); 59 } 60 } Listagem 4.11: fcrossbilateralfilter.glsl (Adaptado de [36]).

83 Implementação de Shaders em GLSL Shaders do Filtro Espaço-Temporal O método para o processo do Filtro Espaço-Temporal é denominado SpatioTemporalFilter, ele pertence à classe HandleMethod, e aplica os sub-métodos Fill_In e OpticalFlow. A Listagem 4.12 mostra sua aplicação e também os dados de entrada conforme a Figura 4.2-B. A função getstf() (Linha 17) mostra que a textura texfiltesptempant (textura filtrada no intervalo de tempo anterior) ainda é enviada no segundo intervalo de tempo, depois de ser executada (Linha 39). No primeiro intervalo de tempo é aplicado apenas o filtro espacial. Portanto, o peso para o frame no primeiro intervalo de tempo é 0 (Linha 53). Na função ApplySTF(), também pode ser escolhido a opção de aplicar o método OpticalFlow com o parâmetro enableopticalflow (Linha 3). Segundo a Equação 2.13, o Filtro Temporal considera operações no frame do intervalo de tempo anterior. Com a aplicação do fluxo óptico no frame anterior consegue-se obter a ubicação certa do pixel e seu kernel analisado no frame do intervalo de tempo atual. Caso não seja aplicado o método OpticalFlow, o cálculo do Filtro Espaço-Temporal se reduz a uma simples média de dois frames vizinhos. Consequentemente, quando algum objeto da cena está em movimento, a saída da malha mostra artefatos como na Figura No Fragment Shader (Listagem 4.13), o parâmetro enableflow indica habilitar o uso do fluxo óptico. Se ele é falso, o cálculo do pixel central (Linha 52) e de seus vizinhos (Linha 77) no frame, no intervalo de tempo anterior muda, afetando o cálculo da filtragem nesse frame, como mostrado nas Linhas 108 a Gluint SpatioTemporalFilter:: ApplySTF() 2 { 3 if( enableopticalflow ) 4 { 5 if(! PreviusColor ) 6 { 7 PreviusColor = cvcreateimage( cvsize(640, 480), IPL_DEPTH_8U, 3); 8 memcpy( PreviusColor ->imagedata, Color ->imagedata, 640*480*3 ); 9 } 10 OFImage = applyopticalfow(); 11 memcpy( PreviusColor ->imagedata, Color ->imagedata, 640*480*3 ); 12 } 13 STDepth = getstf(color, PreviusColo, OFImage, CBDepth, PreviusSTDepth); 14 previousframefst ++;

84 Capítulo 4. Desenvolvimento do Framework return STDepth 16 } 17 GLuint SpatioTemporalFilter:: getstf( GLuint texcolor, GLuint texcolorant, 18 GLuint texoptflow, GLuint texfillin, GLuint texfiltesptempant) 19 { 20 glbindframebuffer( GL_FRAMEBUFFER, fbostf ); 21 modelviewmatrix. settoidentity(); 22 projectionmatrix. settoidentity(); 23 projectionmatrix. ortho(0, 640,480, 0, -1.0f, 1.0f); 24 if (! mfiltesptempprogram ->bind() ) 25 { 26 qwarning() << " Could not bind shader program to context"; return; 27 } 28 glactivetexture( GL_TEXTURE0 ); 29 glbindtexture( GL_TEXTURE_2D, texcolor ); 30 glactivetexture( GL_TEXTURE1 ); 31 glbindtexture( GL_TEXTURE_2D, texcolorant ); 32 glactivetexture( GL_TEXTURE2 ); 33 glbindtexture( GL_TEXTURE_2D, texoptflow ); 34 glactivetexture( GL_TEXTURE3 ); 35 glbindtexture( GL_TEXTURE_2D, texfillin ); 36 if( previousframefst > 0 ) 37 { 38 glactivetexture( GL_TEXTURE4 ); 39 glbindtexture( GL_TEXTURE_2D, texfiltesptempant ); 40 } 41 mfiltesptempprogram ->setuniformvalue( " currentvideo", 0 ); 42 mfiltesptempprogram ->setuniformvalue( " previousvideo", 1 ); 43 mfiltesptempprogram ->setuniformvalue( " opticalflow", 2 ); 44 mfiltesptempprogram ->setuniformvalue( " currentdistance", 3 ); 45 mfiltesptempprogram ->setuniformvalue( " previousdistance", 4 ); 46 mfiltesptempprogram ->setuniformvalue( " coloursigma", 0.1f ); 47 mfiltesptempprogram ->setuniformvalue( " distancesigma", 0.1f ); 48 mfiltesptempprogram ->setuniformvalue( " flowsigma", 5.0f ); 49 mfiltesptempprogram ->setuniformvalue( " spatialsigma", 5.0f ); 50 if( previousframefst > 0) 51 mfiltesptempprogram ->setuniformvalue( " falloffweight", 0.1f ); 52 else 53 mfiltesptempprogram ->setuniformvalue( " falloffweight", 0.0f ); 54 if( enableopticalflow) 55 mfiltesptempprogram ->setuniformvalue(" enableflow", TRUE); 56 else 57 mfiltesptempprogram ->setuniformvalue(" enableflow", FALSE); 58 vbovertices ->bind(); 59 mfiltesptempprogram ->setattributebuffer(" vposition", GL_FLOAT, 0, 4); 60 mfiltesptempprogram ->enableattributearray(" vposition"); 61 gldrawarrays( GL_TRIANGLE_FAN, 0, 4 ); 62 vbovertices ->release(); 63 mfiltesptempprogram ->release(); return STDepth; 66 } Listagem 4.12: SpatioTemporalFilter.cpp: funções ApplySTF() e GetSTF().

85 Implementação de Shaders em GLSL 1 out vec4 fragcolor; 2 // input textures 3 uniform sampler2d currentvideo; 4 uniform sampler2d previousvideo; 5 uniform sampler2d opticalflow; 6 uniform sampler2d currentdistance; 7 uniform sampler2d previousdistance; 8 // filter parameters 9 uniform float coloursigma; 10 uniform float distancesigma; 11 uniform float flowsigma; 12 uniform float spatialsigma; 13 uniform float falloffweight; 14 uniform bool enableflow; void main() 17 { 18 // assuming every texture has the same size 19 vec2 size = texturesize2d( currentvideo, 0 ); // precompute 1 / sigma ^2 22 float isigmas = 1.0 / ( 2.0 * spatialsigma * spatialsigma ); 23 float isigmac = 1.0 / ( 2.0 * coloursigma * coloursigma ); 24 float isigmad = 1.0 / ( 2.0 * distancesigma * distancesigma ); 25 float isigmaf = 0.0; if( enableflow ) 28 isigmaf = 1.0 / ( 2.0 * flowsigma * flowsigma ); // truncate Gaussian after 2 sigma 31 int radius = int( ceil(2.0 * spatialsigma)); // homogeneous accumulator of values, i.e. (w * value, w) 34 vec2 acc = vec2(0.0); 35 vec2 acc1 = vec2(0.0); 36 vec2 acc2 = vec2(0.0); // colour and distance values at the central pixel 39 vec3 centrec = texture2d( currentvideo, gl_fragcoord.xy / size). rgb; 40 vec4 centred = texture2d( currentdistance, gl_fragcoord.xy / size); 41 // motion - compensated centre of kernel in previous frame 42 vec4 centreflow; 43 vec2 previouscentrecoords; if( enableflow ) 46 { 47 centreflow = texture2d( opticalflow, gl_fragcoord.xy / size); 48 previouscentrecoords = 49 vec2( gl_fragcoord.x- centreflow.x, gl_fragcoord.y+centreflow.y)/ size; 50 } 51 else 52 previouscentrecoords = vec2( gl_fragcoord.x, gl_fragcoord.y) / size; 53

86 Capítulo 4. Desenvolvimento do Framework // loop over rectangular 2D kernel of pixels centred around gl_fragcoord.xy 55 for( float yi =gl_fragcoord.y - radius;yi <= gl_fragcoord.y + radius;yi++) 56 { 57 for( float xi =gl_fragcoord.x - radius;xi <= gl_fragcoord.x + radius;xi++) 58 { 59 // ignore out of range pixels 60 if(xi >= 0 && xi < size.x && yi >= 0 && yi < size.y) 61 { 62 //---- current frame // distance of kernel pixel in current frame 64 vec2 currentcoords = vec2(xi, yi) / size; 65 float currentd = texture2d( currentdistance, currentcoords).a; 66 float currentdr = texture2d( currentdistance, currentcoords).r; // optical flow at the kernel pixel 69 vec4 flows = vec4(0.0,0.0,0.0,0.0); 70 vec2 previouscoords; 71 if( enableflow ) 72 { 73 flows = texture2d( opticalflow, currentcoords); 74 previouscoords = vec2(xi - flows.x, yi + flows.y) / size; 75 } 76 else 77 previouscoords = vec2(xi, yi) / size; // ignore pixels with invalid depth 80 if( currentd!= 0.0f) 81 { 82 // colour of kernel pixel in current frame 83 vec3 currentc = texture2d( currentvideo, currentcoords). rgb; 84 // compute pixel weight, using exp(a) * exp(b) = exp(a + b); 85 float w = 0.0f; 86 // spatial weight 87 vec2 deltas = vec2(xi, yi) - gl_fragcoord.xy; 88 w += isigmas * dot( deltas, deltas); 89 // colour weight 90 vec3 deltac = currentc - centrec; if( enableflow ) 93 w+= clamp(2- length( flows.zw)/ flowsigma,0.0,1.0)* isigmac* dot( deltac, deltac); 94 else 95 w += isigmac * dot( deltac, deltac); // depthmap distance weight ( ignore if central pixel invalid) 98 float deltad1 = currentdr - centred.r; 99 if( centred.a!= 0.0f) w += isigmad * ( deltad1 * deltad1); 100 acc1 += exp(-w) * (1.0 - falloffweight) * vec2( currentdr, 1.0); 101 // depth distance weight 102 float deltad2 = currentd - centred.a; 103 if( centred.a!= 0.0f) w += isigmad * ( deltad2 * deltad2); 104 acc2 += exp(-w) * (1.0 - falloffweight) * vec2( currentd, 1); 105 }

87 Implementação de Shaders em GLSL //---- previous frame if( falloffweight == 0.0) continue; 109 if( previouscoords.x < 0 previouscoords.x >= 1) continue; 110 if( previouscoords.y < 0 previouscoords.y >= 1) continue; 111 // distance of kernel pixel in current frame 112 float previousd = texture2d( previousdistance, previouscoords).a; 113 float previousdr = texture2d( previousdistance, previouscoords).r; 114 // ignore pixels with invalid depth 115 if( previousd!= 0.0f) 116 { 117 // colour of kernel pixel in previous frame 118 vec3 previousc = texture2d( previousvideo, previouscoords). rgb; 119 // compute pixel weight, using exp(a) * exp(b) = exp(a + b); 120 float w = 0.0f; 121 // spatial weight 122 // vec2 deltas = vec2(xi, yi) - gl_fragcoord.xy; 123 vec2 deltas = size * ( previouscoords - previouscentrecoords); 124 w += isigmas * dot( deltas, deltas); 125 // flow weight 126 if( enableflow ) 127 w += isigmaf * dot( flows.xy, flows.xy); 128 // colour weight 129 vec3 deltac = previousc - centrec; 130 w += isigmac * dot( deltac, deltac); 131 // DepthMap distance weight ( ignore if central pixel invalid) 132 float deltad1 = previousdr - centred.r; 133 if( centred.a!= 0.0f) w += isigmad * ( deltad1 * deltad1); 134 acc1 += exp(-w) * falloffweight * vec2( previousdr, 1); 135 // distance 136 float deltad2 = currentd - centred.a; 137 if( centred.a!= 0.0f) w += isigmad * ( deltad2 * deltad2); 138 acc2 += exp(-w) * falloffweight * vec2( currentd, 1); 139 } 140 } 141 } 142 } 143 } 144 // write back filtered point 145 if( acc1.y <= 0.0) 146 // just return black if there were no valid data samples in the kernel 147 fragcolor = vec4(0.0, 0.0, 0.0, 0.0); 148 else 149 fragcolor = vec4( acc1. xxx/ acc1.yyy, acc2.x/ acc2.y ); 150 } Listagem 4.13: fspatiotemporalfilter.glsl (Adaptado de [36]). Por outro lado, todos os métodos dos processos de preenchimento e filtragem são aplicados como render-to-texture. Para que eles sejam mostrados na tela, são enviados à GPU seus respectivos identificadores de textura, como descrito no fluxograma da Figura 4.3. Usando os

88 Capítulo 4. Desenvolvimento do Framework 72 shaders das Listagens 4.14 e 4.15, os resultados de qualquer método podem ser mostrados na tela. 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 4 uniform mat4 modelviewmatrix; 5 uniform mat4 projectionmatrix; 6 7 out vec2 ftexcoord; 8 9 void main( void ) 10 { 11 ftexcoord = vtexcoord; 12 vec4 eyeposition = modelviewmatrix * vposition; 13 gl_position = projectionmatrix * eyeposition; 14 } Listagem 4.14: vtexturatoscreen.glsl. 1 out vec4 fragcolor; 2 3 in vec2 ftexcoord; 4 uniform sampler2d texcolormap; 5 6 void main( void ) 7 { 8 fragcolor = texture2d( texcolormap, ftexcoord); 9 fragcolor.a = 1.0; 10 } Listagem 4.15: ftexturatoscreen.glsl Shaders para Nuvem de Pontos e Wireframe As distâncias originais de profundidade da cena, armazenadas na coordenada z, são mostradas como nuvem de pontos usando o Vertex e Fragment Shader das Listagens 4.16 e 4.17 respectivamente. As propriedades dos vértices como posição e cor são enviadas para GPU tal como descrito no fluxograma da Figura 4.4. Para o caso das profundidades filtradas, a Listagem 4.18 mostra que as posições dos vértices são atualizadas na coordenada z (Linha 16), recuperando e copiando da textura de profundidade filtrada texdeptthfilt o valor a. A cor é recuperada da textura da imagem de cor texcolor para cada vértice (Linha 17).

89 Implementação de Shaders em GLSL 1 in vec4 vposition; 2 in vec4 vcolor; 3 4 uniform mat4 modelviewmatrix; 5 uniform mat4 projectionmatrix; 6 7 out vec4 color; 8 9 void main( void ) 10 { 11 color = vcolor; 12 vec4 eyeposition = modelviewmatrix * vposition; 13 gl_position = projectionmatrix * eyeposition; 14 } 1 out vec4 fragcolor; 2 3 in vec4 color 4 5 void main( void ) 6 { 7 fragcolor = color; 8 } 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 out vec4 color; 4 5 uniform mat4 modelviewmatrix; 6 uniform mat4 projectionmatrix; 7 uniform sampler2d texdeptthfilt; 8 uniform sampler2d texcolor; 9 10 void main() 11 { Listagem 4.16: vpointcloudcol.glsl. Listagem 4.17: fpointcloudcol.glsl. 12 vec4 vertexcoord = vposition; 13 vec2 tsize = vec2(1) / texturesize2d( texdepthfilt, 0); 14 ivec2 texelpos = ivec2( vtexcoord); 15 texelpos=clamp( texelpos, ivec2(0), texturesize( texdepthfilt,0)-ivec2(1)); 16 vertexcoord.z = texelfetch( texdeptthfilt, texelpos, 0).a; 17 vcolor. rgb = texture2d( texcolor,( vtexcoord.xy+vec2(0.0,0.0))* tsize). rgb; 18 vcolor.a = 1.0; 19 color = vcolor; vec4 eyeposition = modelviewmatrix * vertexcoord; 22 gl_position = projectionmatrix * eyeposition; 23 } Listagem 4.18: vpointclouddepthfilt.glsl.

90 Capítulo 4. Desenvolvimento do Framework 74 Outro método de visualização da cena consiste em mostrar a malha em forma de wireframe. Primeiro se define a estrutura de malha usando a nuvem de pontos adquirida. A Figura 4.7 mostra como se encontram localizados esses pontos e como se define a estrutura da malha. Assim, para realizar a visualização, são usadas faces triangulares formadas através da definição de índices como apresentado na Listagem 4.19, na função createvbos(), Linhas 14 a 16. Figura 4.7: Estrutura da malha com faces triangulares. O ponto vermelho é o ponto comum entre as faces triangulares vizinhas, os índices i,j indicam a posição desse ponto. 1 void Wireframe:: createvbos() 2 { 3 glgenvertexarrays( 1, & VAO ); 4 glbindvertexarray( VAO ); 5 numvertices = 480*640; 6 numindices = ((640*2) -2)*(480-1)*3; 7 int k = 0; 8 indices = new unsigned int [ numindices]; 9 vertices = new QVector4D[ nvertices];// vertices used later - not removed 10 for ( unsigned int i = 0; i < 480; i++) 11 for ( unsigned int j = 0; j < 640; j++) 12 if( i<479 && j <639) 13 { indices[k] = i*640+j; indices[k+1] = (i+1)*640+j; 14 indices[k+2] = i*640+( j+1); indices[k+3] = i*640+( j+1); 15 indices[k+4] = (i+1)*640+j; indices[k+5] = (i+1)*640+( j+1); 16 k=k+6; 17 } 18 vbovertices = createobjetobuffer( QOpenGLBuffer:: VertexBuffer, 19 QOpenGLBuffer:: DynamicDraw, vertices, numvertices* sizeof( QVector4D) ); 20 deletevector( vertices); 21 vboindices = createobjetobuffer( QOpenGLBuffer:: IndexBuffer, 22 QOpenGLBuffer:: StaticDraw, indices, numindices* sizeof( unsigned int) ); 23 deletevector( indices); 24 glbindvertexarray (0); 25 } Listagem 4.19: Wireframe.cpp: método CreateVBOs().

91 Implementação de Shaders em GLSL A implementação do wireframe é feita em shaders, onde é aproveitado o rendering padrão das faces de uma malha para desenhar as linhas do wireframe. Para isso, no Geometry Shader, é utilizado a primitiva TRIANGLE_STRIP como mostra a Listagem Nesse shader é recuperada a posição do vértice de cada primitiva de entrada (a primitiva é especificada na Linha 1). Além disso são calculadas as transformações de vista e projeção. Aqui adicionamos o atributo weight para especificar um peso da borda em cada um desses vértices. Assim, quando esses dados são enviados ao Fragment Shader (Listagem 4.22), os pixels próximos às bordas de uma face poligonal da malha são pintados. 1 in vec4 vposition; 2 3 void main() 4 { 5 gl_position = vposition; 6 } Listagem 4.20: vwireframe.glsl. 1 layout( triangles) in; 2 layout( triangle_strip, max_vertices = 3) out; 3 4 uniform mat4 modelviewmatrix; 5 uniform mat4 projectionmatrix; 6 7 out vec3 weight; 8 9 void main() 10 { 11 weight = vec3(1.0, 0.0, 0.0); 12 gl_position = projectionmatrix * modelviewmatrix * gl_in[0]. gl_position; 13 EmitVertex(); weight = vec3(0.0, 1.0, 0.0); 16 gl_position = projectionmatrix * modelviewmatrix * gl_in[1]. gl_position; 17 EmitVertex(); weight = vec3(0.0, 0.0, 1.0); 20 gl_position = projectionmatrix * modelviewmatrix * gl_in[2]. gl_position; 21 EmitVertex(); EndPrimitive(); 24 } Listagem 4.21: gwireframe.glsl.

92 Capítulo 4. Desenvolvimento do Framework 76 1 out vec4 fragcolor; 2 3 in vec3 weight; 4 5 float DISCARD_AT = 0.1; 6 float BACKGROUND_AT = 0.05; 7 8 void main() 9 { 10 vec3 color = vec3(0.9,0.6,0.3); 11 vec3 BACKGROUND = vec3(0.0,0.0,0.0); 12 float mindist = min( weight.r, min( weight.g, weight.b)); 13 if ( mindist > DISCARD_AT) discard; 14 vec3 intensity = mindist > BACKGROUND_AT? BACKGROUND : color; fragcolor = vec4( intensity, 1.0); 17 } Listagem 4.22: fwireframe.glsl. Para o caso das profundidades filtradas, a entrada dos dados mudam como na Figura 4.5. A Listagem 4.23 mostra que as posições dos vértices são atualizadas na coordenada z da mesma forma como foi descrito para o caso da nuvem de pontos. 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 4 uniform sampler2d texcolormap; 5 6 void main() 7 { 8 vec4 vertexcoord = vposition; 9 vec2 texelsize = vec2(1) / texturesize2d( texcolormap, 0); 10 ivec2 texelpos = ivec2( vtexcoord + 0.5); 11 texelpos = clamp( texelpos, ivec2(0), texturesize( texcolormap,0)-ivec2(1)); 12 vertexcoord.z = texelfetch( texcolormap, texelpos, 0).a; gl_position = vertexcoord; 15 } Listagem 4.23: vwireframedepthfilt.glsl Phong Shading para Dados do Kinect Um importante método de tonalização de malhas poligonais é o Phong Shading. Esse método usa o modelo de iluminação de Phong [2], o qual é compatível com o modelo do pipeline

93 Implementação de Shaders em GLSL que ilumina cada polígono localmente durante a rasterização. O Phong Shading requer que o processamento seja aplicado a cada fragmento (por isso o nome per fragment shading ) e portanto deve ser implementado através do fragment shader. O cálculo do modelo modificado do Phong Shading com o vetor halfway h, utilizado neste trabalho, está na Equação 4.1. Esta considera uma fonte de luz I longe da superfície da cena: I = k d L d max (l n, 0) + k s L s max ( (n h) ɛ, 0 ) + k a L a. (4.1) I é composto pela adição de três componentes: quantidade de luz difusa k d L d max (l n, 0), se l e n são normalizados, quantidade de luz especular k s L s max ((n h) ɛ, 0) e quantidade de luz ambiente k a L a. L d, L s, L a são as intensidades de luz de cada tipo. k d, k s, k a são coeficientes de absorção que determinam quanto de cada tipo de luz é refletida. ɛ é o coeficiente de brilho na componente de luz especular. Na implementação, para aplicar o método, são necessários os dados das propriedades dos materiais e das luzes, bem como as normais. Esses dados devem ser calculados pela aplicação e servirão de entradas para os shaders. n n 1 n 2 n 3 n 4 Figura 4.8: Cálculo do vetor normal, n é obtido das normais vizinhas ao vértice (Fonte [2]). Neste trabalho, devido a mudança constante da geometria da cena, o cálculo das normais é feito na GPU, especificamente no Vertex Shader. Primeiro definimos a estrutura de malha da mesma forma como o wireframe representado na Figura 4.7. A Figura 4.8 mostra as faces que estarão envolvidas no cálculo da normal para um determinado ponto, de acordo com a

94 Capítulo 4. Desenvolvimento do Framework 78 Equação 4.2. n = n 1 + n 2 + n 3 + n 4 n 1 + n 2 + n 3 + n 4. (4.2) Assim, o Vertex Shader, mostrado na Listagem 4.24, recebe e processa atributos do vértice (luz, normal e observador). Tanto a luz como as normais são convertidas à coordenadas de olho. As normais são convertidas através da transformação com a matriz normalmatrix (Linha 90). A luz é convertida através da subtração dela com a posição do olho, Linha 91, já que a luz tem uma localização finita (essa característica é definida com LightPosition.w = 1.0). Por último, o vetor do observador tem direção oposta às coordenadas de olho porque o observador está na origem (Linha 92). A estrutura OpenGL TBO é usada para enviar os dados da nuvem de pontos, da CPU à GPU, como um arranjo no parâmetro uniform samplerbuffer (Linha 10). Logo, os dados são enviados ao geometry shader (Listagem 4.25). Neste trabalho, ainda não são criados novos elementos na geometria e o shader passa apenas os dados de cada triângulo ao Fragment Shader (Listagem 4.26). Aqui, por padrão, as cores dos vértices são interpoladas ao longo do objeto. Da mesma maneira, as normais serão interpolados para cada fragmento. Os dados de luz e materiais são dados enviados pela aplicação. O vetor halfway é calculado através da normalização da soma entre os vetores de luz e observador (Linha 19). Finalmente, as componentes de luz ambiente, difusa e especular são calculadas conforme à Equação 4.1. Para aplicar o Phong Shading são definidas estruturas VBO (Listagem 4.27) na CPU. Após isso, na função DrawGL(), extensão do método paintgl, essas estruturas são enviadas para a GPU fazer o rendering (Listagem 4.28).

95 Implementação de Shaders em GLSL 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 out vec3 fn; 4 out vec3 fe; 5 out vec3 fl; 6 uniform mat3 normalmatrix; 7 uniform mat4 modelviewmatrix; 8 uniform mat4 projectionmatrix; 9 uniform vec4 LightPosition; 10 uniform samplerbuffer tbosampler; vec3 gennormales() 13 { 14 int i = int( vtexcoord.x); 15 int j = int( vtexcoord.y); ivec2 indices [7]; 18 indices[0] = ivec2(i-1,j); 19 indices[1] = ivec2(i-1,j+1); 20 indices[2] = ivec2(i,j-1); 21 indices[3] = ivec2(i,j); 22 indices[4] = ivec2(i,j+1); 23 indices[5] = ivec2(i+1,j-1); 24 indices[6] = ivec2(i+1,j); ivec3 faces[6]; 27 faces[0] = ivec3(0,2,3); 28 faces[1] = ivec3(1,0,3); 29 faces[2] = ivec3(4,1,3); 30 faces[3] = ivec3(3,2,5); 31 faces[4] = ivec3(6,3,5); 32 faces[5] = ivec3(4,3,6); vec3 normal = vec3(0.0,0.0,0.0); for ( int k = 0; k < 6; k++) 37 { 38 vec3 v1 = vec3(0.0,0.0,0.0); 39 vec3 v2 = vec3(0.0,0.0,0.0); 40 vec3 v3 = vec3(0.0,0.0,0.0); i = indices[ faces[k].x].x; 43 j = indices[ faces[k].x].y; if( (i >= 0 && i < 480) && (j >= 0 && j < 640) ) 46 { 47 int coord = int(i*640+j); 48 v1 = texelfetch( tbosampler, coord). xyz; 49 } 50 else 51 continue; i = indices[ faces[k].y].x;

96 Capítulo 4. Desenvolvimento do Framework j = indices[ faces[k].y].y; if( (i >= 0 && i < 480) && (j >= 0 && j < 640) ) 57 { 58 int coord = int(i*640+j); 59 v2 = texelfetch( tbosampler, coord). xyz; 60 } 61 else 62 continue; i = indices[ faces[k].z].x; 65 j = indices[ faces[k].z].y; if( (i >= 0 && i < 480) && (j >= 0 && j < 640) ) 68 { 69 int coord = int(i*640+j); 70 v3 = texelfetch( tbosampler, coord). xyz; 71 } 72 else 73 continue; vec3 facenormal = cross(v2-v1,v3-v1); if(!( isnan( facenormal.x) isnan( facenormal.y) isnan( facenormal.z))) 78 normal += facenormal; 79 } 80 normal = normalize( normal); return normal; 83 } void main( void) 86 { 87 vec4 eyeposition = modelviewmatrix * vposition; 88 vec3 vnormal = gennormales(); fn = normalmatrix * vnormal; 91 fl = LightPosition. xyz - eyeposition. xyz; 92 fe = - eyeposition. xyz; gl_position = projectionmatrix * modelviewmatrix * vposition; 95 } Listagem 4.24: vphong.glsl.

97 Implementação de Shaders em GLSL 1 layout( triangles) in; 2 layout( triangle_strip, max_vertices = 3) out; 3 4 out vec3 GNormal; 5 out vec3 GPosition; 6 out vec3 GLuz; 7 8 in vec3 fn[]; 9 in vec3 fe[]; 10 in vec3 fl[]; void main() 13 { 14 GNormal = fn[0]; 15 GPosition = fe[0]; 16 GLuz = fl[0]; 17 gl_position = gl_in[0]. gl_position; 18 EmitVertex(); GNormal = fn[1]; 21 GPosition = fe[1]; 22 GLuz = fl[1]; 23 gl_position = gl_in[1]. gl_position; 24 EmitVertex(); GNormal = fn[2]; 27 GPosition = fe[2]; 28 GLuz = fl[2]; 29 gl_position = gl_in[2]. gl_position; 30 EmitVertex(); EndPrimitive(); 33 } Listagem 4.25: gphong.glsl. 1 out vec4 fragcolor; 2 in vec3 GNormal; 3 in vec3 GPosition; 4 in vec3 GLuz; 5 struct MaterialInfo { 6 vec4 ambientproduct; // Ambient reflectivity 7 vec4 diffuseproduct; // Diffuse reflectivity 8 vec4 specularproduct; // Specular reflectivity 9 float shininess; // Specular shininess factor 10 }; 11 uniform MaterialInfo M; void main() 14 { 15 // I = Kd*Id*(L.N) + Ks*Is*(N.H)^e + Ka*Ia 16 vec3 N = normalize( GNormal); 17 vec3 E = normalize( GPosition);

98 Capítulo 4. Desenvolvimento do Framework vec3 L = normalize( GLuz); 19 vec3 H = normalize(l + E); 20 float NdotL = dot(n, L); 21 float kd = max(ndotl,0.0); 22 float ks = ( NdotL < 0.0)? 0.0 : pow( max( dot(n,h),0.0),m. shininess); 23 vec4 ambient = M. ambientproduct; 24 vec4 diffuse = kd * M. diffuseproduct; 25 vec4 specular = ks * M. specularproduct; fragcolor = ambient + diffuse + specular; 28 fragcolor.a = 1.0; 29 } Listagem 4.26: fphong.glsl. 1 void Phong:: createvbos() 2 { 3 glgenvertexarrays( 1, & VAO ); 4 glbindvertexarray( VAO ); 5 numvertices = 480*640; 6 numindices = numvertices; 7 numfaces = ((640*2) -2)*(480-1); 8 numindices = numfaces*3; 9 int k = 0; 10 indices = new unsigned int [ numindices]; 11 vertices = new QVector4D[ nvertices]; 12 texcoords = new QVector2D[ nvertices]; for ( unsigned int i = 0; i < 480; i++) 15 for ( unsigned int j = 0; j < 640; j++) 16 { 17 if( i<479 && j <639) 18 { 19 indices[k] = i*640+j; indices[k+1] = (i+1)*640+j; 20 indices[k+2] = i*640+( j+1); indices[k+3] = i*640+( j+1); 21 indices[k+4] = (i+1)*640+j; indices[k+5] = (i+1)*640+( j+1); 22 k=k+6; 23 } 24 texcoords[i*640+j] = QVector2D(i,j); 25 } 26 // vertices used later - not removed 27 vbovertices = createobjetobuffer( QOpenGLBuffer:: VertexBuffer, 28 QOpenGLBuffer:: DynamicDraw, vertices, numvertices* sizeof( QVector4D) ); 29 vbotexcoords = createobjetobuffer( QOpenGLBuffer:: VertexBuffer, 30 QOpenGLBuffer:: StaticDraw, texcoords, numvertices * sizeof( QVector2D) ); 31 deletevector( texcoords); 32 vboindices = createobjetobuffer( QOpenGLBuffer:: IndexBuffer, 33 QOpenGLBuffer:: StaticDraw, indices, numindices* sizeof( unsigned int) ); 34 deletevector( indices); 35 glbindvertexarray (0); 36 } Listagem 4.27: Phong.cpp: método CreateVBOs().

99 Implementação de Shaders em GLSL 1 void Phong:: DrawGL() 2 { 3 modelviewmatrix. settoidentity(); 4 modelviewmatrix. lookat( camera.eye, camera.at, camera.up); 5 modelviewmatrix. scale(zoom, zoom, 1.0); 6 modelviewmatrix. rotate( trackball. getrotation()); 7 modelviewmatrix. translate(0.0,0.0,- dz); 8 modelviewmatrix. rotate(90,0.0, 0.0,1.0); 9 projectionmatrix. settoidentity(); 10 projectionmatrix. ortho(-0.50f, 0.50, -0.50f, 0.50f, 0.0, 200.0f); if (! shaderprogram ->bind() ) 13 { 14 qwarning() << " Could not bind shader program to context"; return; 15 } 16 normalmatrix = modelviewmatrix. normalmatrix(); shaderprogram ->setuniformvalue( " modelviewmatrix", modelviewmatrix ); 19 shaderprogram ->setuniformvalue( " projectionmatrix", projectionmatrix ); 20 shaderprogram ->setuniformvalue( " nwidgetview", nwidgetview ); 21 shaderprogram ->setuniformvalue( " normalmatrix", normalmatrix ); 22 shaderprogram ->setuniformvalue( " LightPosition", LightPosition ); 23 shaderprogram ->setuniformvalue( "M. ambientproduct", ambientproduct ); 24 shaderprogram ->setuniformvalue( "M. diffuseproduct", diffuseproduct ); 25 shaderprogram ->setuniformvalue( "M. specularproduct", specularproduct ); 26 shaderprogram ->setuniformvalue( "M. shininess", 100.0f ); 27 shaderprogram ->setuniformvalue( " tbosampler", 0 ); settexturebufferdata(); // passing array vertices as TBO 30 glactivetexture( GL_TEXTURE0 ); 31 glbindtexture( GL_TEXTURE_BUFFER, _teximg ); vbovertices ->bind(); 34 getpontos(); // update vertices with methods map()/ unmap() shaderprogram ->setattributebuffer(" vposition", GL_FLOAT, 0, 4); 37 shaderprogram ->enableattributearray(" vposition"); vbotexcoords ->bind(); 40 shaderprogram ->setattributebuffer( " vtexcoord", GL_FLOAT, 0, 2 ); 41 shaderprogram ->enableattributearray( " vtexcoord" ); vboindices ->bind(); 44 glbindvertexarray( VAO); 45 gldrawelements( GL_TRIANGLES, numfaces*3, GL_UNSIGNED_INT, 0 ); vbotexcoords ->release(); 48 vbovertices ->release(); 49 vboindices ->release(); 50 shaderprogram ->release(); 51 } Listagem 4.28: Phong.cpp: método DrawGL().

100 Capítulo 4. Desenvolvimento do Framework Cartoon Shading No Cartoon Shading, estilo típico de desenho animado, também é aplicado o per fragment shading. Como o Phong Shading, ele inclui parte dos passos do sombreamento descrito na Seção anterior, mas este caso envolve apenas as componentes de luz ambiente e difusa. A ideia é quantizar o termo cosseno da componente difusa da Equação 4.1. Em outras palavras, o valor do produto escalar l n, que é usado normalmente na componente difusa, está restrito a um número fixo de valores possíveis. Por exemplo, a Tabela 4.1 ilustra o conceito de quatro níveis. Tabela 4.1: Níveis da Componente Difusa. Valor utilizado para cada ângulo entre a fonte de luz l e o vetor normal da superfície n. l n Valor Usado Entre 1,00 e 0,75 0,75 Entre 0,75 e 0,50 0,50 Entre 0,50 e 0,25 0,25 Entre 0,25 e 0,00 0,00 Desta forma, ao restringir o valor do termo cosseno, a tonalização apresenta descontinuidades fortes a partir de um nível para outro, simulando os traços de caneta nos desenhos de animação à mão livre. Este efeito, além de reduzir o número de cores que são usadas, inclui contornos pretos ao redor das silhuetas e ao longo de outras bordas de alguma forma existente na cena. A técnica usada para detecção de bordas foi descrita na Seção 2.2. Ela pode ser aplicada na imagem de cor ou na profundidade devido ao fato que estamos trabalhando com dados RGB-Z. Para isso, no Vertex Shader (Listagem 4.29) é calculado a cor de cada vértice (Linha 22), os vetores luz (Linha 30) e normal (Linha 31). Todos eles, juntamente com a coordenada de textura, são passados para o Fragment Shader (Listagem 4.30). Aqui é definido o número de níveis, levels, da componente difusa (Linha 12). Primeiro é calculado normalmente o termo difuso (Linha 44). O valor dessa saída é entre 0 e 1. A linha seguinte visa quantizar este componente, multiplicando o valor anterior por levels e passando o resultado à função

101 Implementação de Shaders em GLSL floor() (arrendondá-lo a um número para baixo em direção a zero); assim, esse resultado será um número inteiro entre 0 e levels 1. Imediatamente, esse valor é dividido por levels (multiplicando por scalefactor), dimensioná-lo novamente para ficar entre 0 e 1. Portanto, o resultado é um valor que pode ser um dos níveis de valores possíveis espaçadas entre 0 e 1 como é mostrado na Tabela 4.1 com levels = 4. Este resultado é então multiplicado por M.diffuseProduct, que é o termo de refletividade difusa (Linha 47). Finalmente, os componentes difusos e ambientes são combinados a fim de se obter a cor final para o fragmento, sem deixar de multiplicá-la pelo resultado da função sobel(), que obtém os contornos pretos ao redor das bordas na imagem de cor. 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 4 uniform mat4 modelviewmatrix; 5 uniform mat4 projectionmatrix; 6 uniform mat3 normalmatrix; 7 uniform vec4 LightPosition; 8 uniform sampler2d texnormalmap; 9 uniform sampler2d texcolormap; out vec3 fn; 12 out vec3 fl; 13 out vec4 color; 14 out vec2 ftexcoord; void main() 17 { 18 vec2 tsize = vec2(1) / texturesize2d( texcolormap, 0); ivec2 texelpos = ivec2( vtexcoord); 21 texelpos =clamp( texelpos, ivec2(0), texturesize( texcolormap,0)-ivec2(1)); 22 color. rgb=texture2d( texcolormap,( vtexcoord.xy+vec2(0.0,0.0))* tsize). rgb; 23 color.a = 1.0; ftexcoord = vtexcoord; vec3 vnormal = texelfetch( texnormalmap, texelpos, 0). rgb; vec4 eyeposition = modelviewmatrix * vposition; 30 fn = normalmatrix * vnormal; 31 fl = LightPosition. xyz - eyeposition. xyz; 32 gl_position = projectionmatrix * eyeposition; 33 } Listagem 4.29: veffectcolormap.glsl.

102 Capítulo 4. Desenvolvimento do Framework 86 1 out vec4 fragcolor; 2 in vec3 fn; 3 in vec3 fl; 4 in vec4 color; 5 in vec2 ftexcoord; 6 struct MaterialInfo { 7 vec4 ambientproduct; // Ambient reflectivity 8 vec4 diffuseproduct; // Diffuse reflectivity 9 }; 10 uniform MaterialInfo M; 11 uniform sampler2d texcolormap; 12 const float levels = 4.0; 13 const float scalefactor = 1.0 / levels; vec3 sobel() 16 { 17 vec3 t1,t2,t3,t4,t5,t6,t7,t8,t9; 18 // look up image of the 8 neighbours 19 vec2 texelsize = vec2(1) / texturesize2d( texcolormap, 0); 20 t1 =texture2d( texcolormap,( ftexcoord.xy+vec2(-1.0,-1.0))* texelsize). rgb; 21 t2 =texture2d( texcolormap,( ftexcoord.xy+vec2(0.0,-1.0))* texelsize). rgb; 22 t3 =texture2d( texcolormap,( ftexcoord.xy+vec2(1.0,-1.0))* texelsize). rgb; 23 t4 =texture2d( texcolormap,( ftexcoord.xy+vec2(-1.0,0.0))* texelsize). rgb; 24 t5 =texture2d( texcolormap, ftexcoord.xy * texelsize). rgb; 25 t6 =texture2d( texcolormap,( ftexcoord.xy+vec2(1.0,0.0))* texelsize). rgb; 26 t7 =texture2d( texcolormap,( ftexcoord.xy+vec2(-1.0,1.0))* texelsize). rgb; 27 t8 =texture2d( texcolormap,( ftexcoord.xy+vec2(0.0,1.0))* texelsize). rgb; 28 t9 =texture2d( texcolormap,( ftexcoord.xy+vec2(1.0,1.0))* texelsize). rgb; 29 vec3 xx = t * t2 + t3 - t7-2.0* t8 - t9; 30 vec3 yy = t1 - t * t4-2.0* t6 + t7 - t9; 31 vec3 rr = sqrt(xx * xx + yy * yy); 32 float y = (rr.r + rr.g + rr.b) / 3.0; 33 if (y > 0.25) 34 return vec3(0.0, 0.0, 0.0); 35 else 36 return vec3(1.0, 1.0, 1.0); 37 } void main() 40 { 41 vec3 N = normalize(fn); 42 vec3 L = normalize(fl); 43 float NdotL = dot(n, L); 44 float kd = max(ndotl,0.0); 45 float f = floor(kd* levels); 46 vec4 diffuse = M. diffuseproduct * f * scalefactor; 47 vec4 ambient = color ; 48 fragcolor = ambient + diffuse; 49 fragcolor.a = 1.0; 50 fragcolor. rgb = fragcolor. rgb * sobel(); 51 } Listagem 4.30: fcartoonshading.glsl.

103 Implementação de Shaders em GLSL Carregador de Arquivos Nesta seção são apresentadas as considerações a serem tomadas para a utilização do carregador de arquivos shaders a fim de aplicar um efeito online, bem como a execução de um exemplo simples. O efeito pode ser aplicado sobre a imagem de cor ou sobre a malha. Para qualquer um dos dois pode-se usar os mesmos dados enviados da CPU para GPU. Dados enviados da CPU à GPU Como é mostrado na Listagem 4.31, além dos dados habituais de posição e sombreamento, os shaders são habilitados para trabalhar com três texturas. Essas texturas são de tipo uniform sampler2d. Elas têm as seguintes características: texcolormap, textura da imagem de cor; texdepthmap, textura do mapa de profundidade. Ela armazena tons de cinza do pixel com valores entre 0 e 1 na propriedade rgb. Na propriedade a são armazenadas as distâncias reais de profundidade filtrada (mesmo para valores superiores a 1); texnormalmap, textura de normais dos vértices previamente calculados, onde o vetor normal vec3 é armazenado na propriedade rgb da textura. Também, na propriedade a são armazenadas as distâncias reais de profundidade filtrada (a fim de ter disponíveis todos os dados da profundidade em uma única textura); No caso de aplicar um efeito na malha, deve ser considerado no Vertex Shader a atualização da coordenada z da posição do vértice. Na Listagem 4.32, Linha 7, a textura texnormalmap é atualizada na propriedade a. É também apresentado a obtenção do vetor normal na Linha 11. Para acessar aos dados de textura podem ser usadas as funções texelfetch ou texture2d, tomando cuidado com índices fora do limite e a mudança dos tipos de índices de int para float.

104 Capítulo 4. Desenvolvimento do Framework 88 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 4 uniform mat4 modelviewmatrix; 5 uniform mat4 projectionmatrix; 6 uniform mat3 normalmatrix; 7 uniform vec4 LightPosition; 8 9 struct MaterialInfo { 10 vec4 ambientproduct; // Ambient reflectivity 11 vec4 diffuseproduct; // Diffuse reflectivity 12 vec4 specularproduct; // Specular reflectivity 13 float shininess; // Specular shininess factor 14 }; 15 uniform MaterialInfo M; uniform sampler2d texnormalmap; 18 uniform sampler2d texcolormap; 19 uniform sampler2d texdepthmap; Listagem 4.31: dadosshader.glsl. 1 void main() 2 { 3 vec4 vertexcoord = vposition; 4 5 ivec2 texelpos = ivec2( vtexcoord); 6 texelpos=clamp( texelpos, ivec2(0), texturesize( texnormalmap, 0)-ivec2(1)); 7 vertexcoord.z = texelfetch( texnormalmap, texelpos, 0).a; ftexcoord = vtexcoord; 11 vec3 vnormal = texelfetch( texnormalmap, texelpos, 0). rgb; vec4 eyeposition = modelviewmatrix * vertexcoord; 14 fn = normalmatrix * vnormal; 15 fl = LightPosition. xyz - eyeposition. xyz; 16 fe = - eyeposition. xyz; 17 gl_position = projectionmatrix * eyeposition; 18 } Listagem 4.32: veffectdepthmapfilt3d.glsl: método main() para trabalhar com a malha.

105 Implementação de Shaders em GLSL Execução de um exemplo No painel de Load Shaders (um painel reúne componentes da interface gráfica que executam tarefas para realizar uma função do sistema) são carregados os arquivos Vertex Shader e Fragment Shader do efeito. Para o exemplo foi usado o efeito Background Subtraction [36]. Esses arquivos são anexados, compilados e executados em tempo real. A saída do efeito é mostrada na Figura 4.9. Figura 4.9: Uso do carregador de arquivos de shaders com a execução do efeito Background Subtraction. No caso do Vertex Shader mostrado na Listagem 4.33, foi obtida a cor do vértice usando a textura texcolormap (Linha 16), que, junto com a coordenada de textura (Linha 19), são passadas como parâmetros para o Fragment Shader (Listagem 4.34). Aqui foi utilizada a textura texnormalmap para fazer cálculos sobre os dados filtrados da profundidade da cena.

106 Capítulo 4. Desenvolvimento do Framework 90 1 in vec4 vposition; 2 in vec2 vtexcoord; 3 4 uniform mat4 modelviewmatrix; 5 uniform mat4 projectionmatrix; 6 uniform sampler2d texcolormap; 7 8 out vec4 color; 9 out vec2 ftexcoord; void main() 12 { 13 vec2 tsize = vec2(1) / texturesize2d( texcolormap, 0); 14 ivec2 texelpos = ivec2( vtexcoord); 15 texelpos =clamp( texelpos, ivec2(0), texturesize( texcolormap,0)-ivec2(1)); 16 color. rgb=texture2d( texcolormap,( vtexcoord.xy+vec2(0.0,0.0))* tsize). rgb; 17 color.a = 1.0; ftexcoord = vtexcoord; vec4 eyeposition = modelviewmatrix * vposition; 22 gl_position = projectionmatrix * eyeposition; 23 } Listagem 4.33: vbackgroundsubtraction.glsl.

107 Implementação de Shaders em GLSL 1 out vec4 fragcolor; 2 3 in vec4 color; 4 in vec2 ftexcoord; 5 6 uniform sampler2d texnormalmap; 7 8 vec3 getvertex( sampler2d coordinates, vec2 position) 9 { 10 // texel coordinate from texture coordinate 11 ivec2 texelpos = ivec2( position + 0.5); 12 // clamp texel coordinate to valid range 13 texelpos=clamp( texelpos, ivec2(0), texturesize( coordinates, 0)-ivec2(1)); 14 // fetch vertex coordinates, in world coordinates 15 return texelfetch( coordinates, texelpos, 0). aaa; 16 } void main ( void) 19 { 20 vec3 backgroundcolour = vec3(1, 0, 0); 21 vec4 backgroundplane = vec4(0, 0, 1, 1); 22 float planethreshold = 1.5; vec3 shaded = color. xyz; 25 vec2 pos = ftexcoord.xy - 1; 26 // matte: 0 is background, 1 is foreground 27 float matte = 0.0; 28 matte += dot( vec4( getvertex( texnormalmap, pos + vec2(-1,-1)), 1.0), backgroundplane) > planethreshold? 0.0 : 1.0 / 16.0; 29 matte += dot( vec4( getvertex( texnormalmap, pos + vec2(-1, 0)), 1.0), backgroundplane) > planethreshold? 0.0 : 2.0 / 16.0; 30 matte += dot( vec4( getvertex( texnormalmap, pos + vec2(-1, 1)), 1.0), backgroundplane) > planethreshold? 0.0 : 1.0 / 16.0; 31 matte += dot( vec4( getvertex( texnormalmap, pos + vec2( 0,-1)), 1.0), backgroundplane) > planethreshold? 0.0 : 2.0 / 16.0; 32 matte += dot( vec4( getvertex( texnormalmap, pos + vec2( 0, 0)), 1.0), backgroundplane) > planethreshold? 0.0 : 4.0 / 16.0; 33 matte += dot( vec4( getvertex( texnormalmap, pos + vec2( 0, 1)), 1.0), backgroundplane) > planethreshold? 0.0 : 2.0 / 16.0; 34 matte += dot( vec4( getvertex( texnormalmap, pos + vec2( 1,-1)), 1.0), backgroundplane) > planethreshold? 0.0 : 1.0 / 16.0; 35 matte += dot( vec4( getvertex( texnormalmap, pos + vec2( 1, 0)), 1.0), backgroundplane) > planethreshold? 0.0 : 2.0 / 16.0; 36 matte += dot( vec4( getvertex( texnormalmap, pos + vec2( 1, 1)), 1.0), backgroundplane) > planethreshold? 0.0 : 1.0 / 16.0; 37 matte = clamp(matte, 0.0, 1.0); fragcolor = vec4( mix( backgroundcolour, shaded, vec3( matte)), 1.0); 40 } Listagem 4.34: fbackgroundsubtraction.glsl.

108

109 Capítulo 5 Resultados e Discussão Este capítulo está organizado da seguinte forma: na Seção 5.1 são apresentados exemplos da utilização do Framework para o processamento de vídeos RGB-Z e na Seção 5.2 são mostrados e discutidos resultados de desempenho do Framework, limitações e contribuções. 5.1 Utilização do Framework O Framework fornece uma interface gráfica para interagir com o usuário. Essa ferramenta apresenta componentes que possibilitam ao usuário aplicar os diferentes processos do pipeline proposto, bem como recursos e operações de visualização. Na Figura 5.1 é mostrada a interface gráfica. Ela captura e apresenta em cada intervalo de tempo os dados de imagem de cor, mapa de profundidade e nuvem de pontos. Os componentes da interface gráfica são agrupados segundo suas funcionalidades. Esses grupos estão representados na Figura 5.2 e são: A. Painéis Widget que são as janelas de visualização; B. MenuBar com o conjunto de items; C. ToolBar contendo botões para aplicar cada tarefa do processamento;

110 Capítulo 5. Resultados e Discussão 94 Figura 5.1: Interface Gráfica: as janelas inferiores mostram vídeo de cor e vídeo de profundidade. A janela superior mostra a nuvem de pontos, resultante do alinhamento entre imagem de cor e mapa de profundidade. D. Painéis de opções associados aos processos e operações de visualização. Na janela superior da interface gráfica (Figura 5.2-A) são exibidos os resultados de cada processo. Os resultados podem ser apresentados como vídeos (do mesmo modo que os vídeos das janelas inferiores são mostrados) ou, como no exemplo da janela superior da figura, uma malha dinâmica. Além disso, no caso das visualizações da malha, a janela permite interagir com o mouse (trackball virtual e mudança de escala). Um exemplo é mostrado na Figura 5.3. Por outro lado, a barra de menu (Figura 5.2-B) provê funcionalidades para interagir com o sistema, tais como opções de arquivo, diferentes formas de apresentar a malha da cena, métodos do processamento de vídeos RGB-Z; preenchimento de buracos, filtragem espaçotemporal e efeito especial. Essas opções são exibidas na Figura 5.4.

111 Utilização do Framework Figura 5.2: Grupos de componentes da Interface Gráfica. A: janelas de visualização, B: barra de menu, C: barra de tarefas e D: painéis de opções. (a) (b) Figura 5.3: Interação com o mouse. (a): rotação (trackball), (b): escala. Tais menus estão presentes na barra de tarefas (Figura 5.2-C) para facilitar ao usuário na hora de aplicar as diferentes tarefas, como visualização da malha (Figura 5.5); nuvem de pontos com cor da imagem, nuvem de pontos sem cores, malha como wireframe e superfície da malha

112 Capítulo 5. Resultados e Discussão 96 Figura 5.4: Barra de Menus com todas as opções de arquivo (File), visualização (View), preenchimento (Fill-In), filtragem (Filtering) e efeito especial (Effects). com aplicação de iluminação. Da mesma forma, o usuário tem a possibilidade de aplicar quase todos os métodos do pipeline descrito na Seção 2. Para a fase de Preenchimento de Buracos (Figura 5.6) pode-se aplicar os métodos como detecção de bordas no mapa de profundidade, downsampling recursivo (na imagem de cor e do mapa de profundidade até um nível 4), e finalmente, preenchimento das regiões sem informação no mapa de profundidade. Já para a fase de Filtragem Espaço-Temporal (Figura 5.7), o usuário pode aplicar os métodos de Fluxo Óptico na imagem de cor e o Filtro Espaço-Temporal no mapa de profundidade. Por último, um outro processo que pode ser aplicado é Efeito Especial sobre a imagem de cor (Figura 5.8) ou sobre a malha (Figura 5.9). Dentre os painéis de opções (Figura 5.2-D), a aplicação provê um painel carregador de arquivos shader para aplicar um efeito online (detalhes de implementação na Seção 4.4.6). O Framework suporta anexar, compilar e executar em tempo real Vertex, Fragment e Geometry Shader. Como requisito mínimo para aplicar o efeito são necessários os dois primeiros shaders. A Figura 5.9 mostra o carregador de arquivos e a aplicação do efeito na malha. Por outro lado,

113 Utilização do Framework Figura 5.5: Opções de visualização da malha. A: nuvem de pontos com cor da imagem (Col PointCloud), B: nuvem de pontos sem cores (PointCloud), C: malha (Wireframe) e D: superfície da malha com aplicação da iluminação (Surface). o painel superior de opções dispõe duas funções, a primeira é relacionada a operações de visualização, como mostrado na Figura Quando o CheckBox desta opção é selecionado, habilita todas as operações sobre a malha que utilizam os dados do mapa de profundidade filtrado. As operações que estão incluídas são as visualizações da malha e o efeito especial na malha. A segunda opção é associada ao processo de filtragem espaço-temporal. Quando o CheckBox desta opção é selecionado, habilita aplicar o filtro considerando correspondências de movimento (Fluxo Óptico) entre um frame do intervalo de tempo atual a um frame do intervalo de tempo anterior. O resultado pode ser observado na superfície iluminada da malha (Figura 5.11). Um último painel de opções da interface gráfica é aquele que permite mudar a posição da luz na cena. O painel mostra a posição padrão da luz. Ela pode ser mudada pelo usuário interativamente (Figura 5.12). Esta operação pode ser configurada na superfície

114 Capítulo 5. Resultados e Discussão 98 iluminada e nos efeitos, tanto na imagem como na malha. Figura 5.6: Processos de Preenchimento de Buracos. A,B,C,D: Dois níveis de redução de resolução tanto para o mapa de profundidade como para a imagem de cor (Downsampling), E: detecção de bordas no mapa de profundidade (Sobel) e F: preenchimento de buracos no mapa de profundidade (Fill-In).

115 Utilização do Framework Figura 5.7: Processos de filtragem espaço-temporal. A: fluxo óptico na imagem de cor (Optical Flow) e B: filtragem espaço-temporal no mapa de profundidade (Filter ET). Figura 5.8: Processo de efeito especial não-fotorrealísticos sobre a imagem de cor (Cartoon Effect). Figura 5.9: Carregador de arquivos de shaders e execução do efeito na malha.

116 Capítulo 5. Resultados e Discussão 100 Figura 5.10: Visualização da nuvem de pontos colorida, A: com mapa de profundidade sem filtrar e B: com mapa de profundidade filtrado. Figura 5.11: Ativação do método fluxo óptico. A: movimento do objeto com fluxo óptico e B: movimento do objeto sem fluxo óptico. Figura 5.12: Posição da luz na cena. A: Posição padrão e B:posição editada pelo usuário.

4 Experimentos Computacionais

4 Experimentos Computacionais 33 4 Experimentos Computacionais O programa desenvolvido neste trabalho foi todo implementado na linguagem de programação C/C++. Dentre as bibliotecas utilizadas, destacamos: o OpenCV [23], para processamento

Leia mais

Capítulo 5. Figura 5.2. Conector para o monitor.

Capítulo 5. Figura 5.2. Conector para o monitor. Capítulo 5 Placas de vídeo Visão geral das placas de vídeo Esta placa está presente em todos os PCs, exceto nos que possuem placas de CPU com os circuitos de vídeo embutidos. A maioria dos PCs produzidos

Leia mais

Sistemas Operacionais. Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com

Sistemas Operacionais. Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com Sistemas Operacionais Prof. André Y. Kusumoto andrekusumoto.unip@gmail.com Estruturas de Sistemas Operacionais Um sistema operacional fornece o ambiente no qual os programas são executados. Internamente,

Leia mais

Rendering. Por Angelo Luz

Rendering. Por Angelo Luz Rendering Por Angelo Luz Sumário O que é Rendering? Qual a utilidade? Alguns Componentes do Rendering Técnicas mais utilizadas Métodos de utilização O que é Rendering? Rendering é o processo de criação

Leia mais

Base Nacional Comum Curricular 2016. Lemann Center at Stanford University

Base Nacional Comum Curricular 2016. Lemann Center at Stanford University Base Nacional Comum Curricular 2016 Lemann Center at Stanford University Parte II: Base Nacional Comum: Análise e Recomendações da Seção de Matemática Phil Daro Dezembro, 2015 BASE NACIONAL COMUM: ANÁLISE

Leia mais

Guia de utilização da notação BPMN

Guia de utilização da notação BPMN 1 Guia de utilização da notação BPMN Agosto 2011 2 Sumário de Informações do Documento Documento: Guia_de_utilização_da_notação_BPMN.odt Número de páginas: 31 Versão Data Mudanças Autor 1.0 15/09/11 Criação

Leia mais

SEGEMENTAÇÃO DE IMAGENS. Nielsen Castelo Damasceno

SEGEMENTAÇÃO DE IMAGENS. Nielsen Castelo Damasceno SEGEMENTAÇÃO DE IMAGENS Nielsen Castelo Damasceno Segmentação Segmentação Representação e descrição Préprocessamento Problema Aquisição de imagem Base do conhecimento Reconhecimento e interpretação Resultado

Leia mais

36 Anais da Semana de Ciência e Tecnologia, Ouro Preto, v. 4, p. 1 120, 2012.

36 Anais da Semana de Ciência e Tecnologia, Ouro Preto, v. 4, p. 1 120, 2012. CONTROLE À DISTÂNCIA DE UM MOTOR UTILIZANDO RECURSOS DE VISÃO COMPUTACIONAL Matheus Henrique Almeida Nascimento 1, Gean Carlo Neves Correa 2, Cristiano Lúcio Cardoso Rodrigues 3 e Sílvia Grasiella Moreira

Leia mais

ESTEREOSCOPIA INTRODUÇÃO. Conversão de um par de imagens (a)-(b) em um mapa de profundidade (c)

ESTEREOSCOPIA INTRODUÇÃO. Conversão de um par de imagens (a)-(b) em um mapa de profundidade (c) ESTEREOSCOPIA INTRODUÇÃO Visão estereoscópica se refere à habilidade de inferir informações da estrutura 3-D e de distâncias da cena de duas ou mais imagens tomadas de posições diferentes. Conversão de

Leia mais

CADERNOS DE INFORMÁTICA Nº 1. Fundamentos de Informática I - Word 2010. Sumário

CADERNOS DE INFORMÁTICA Nº 1. Fundamentos de Informática I - Word 2010. Sumário CADERNO DE INFORMÁTICA FACITA Faculdade de Itápolis Aplicativos Editores de Texto WORD 2007/2010 Sumário Editor de texto... 3 Iniciando Microsoft Word... 4 Fichários:... 4 Atalhos... 5 Área de Trabalho:

Leia mais

Aula 2 Revisão 1. Ciclo de Vida. Processo de Desenvolvimento de SW. Processo de Desenvolvimento de SW. Processo de Desenvolvimento de SW

Aula 2 Revisão 1. Ciclo de Vida. Processo de Desenvolvimento de SW. Processo de Desenvolvimento de SW. Processo de Desenvolvimento de SW Ciclo de Vida Aula 2 Revisão 1 Processo de Desenvolvimento de Software 1 O Processo de desenvolvimento de software é um conjunto de atividades, parcialmente ordenadas, com a finalidade de obter um produto

Leia mais

Morfologia Matemática Binária

Morfologia Matemática Binária Morfologia Matemática Binária Conceitos fundamentais: (Você precisa entender bem esses Pontos básicos para dominar a área! Esse será nosso game do dia!!! E nossa nota 2!!) Morfologia Matemática Binária

Leia mais

TÉCNICAS DE PROGRAMAÇÃO

TÉCNICAS DE PROGRAMAÇÃO TÉCNICAS DE PROGRAMAÇÃO (Adaptado do texto do prof. Adair Santa Catarina) ALGORITMOS COM QUALIDADE MÁXIMAS DE PROGRAMAÇÃO 1) Algoritmos devem ser feitos para serem lidos por seres humanos: Tenha em mente

Leia mais

Simulador Virtual para Treinamento em Visão de Máquina com LabVIEW

Simulador Virtual para Treinamento em Visão de Máquina com LabVIEW Simulador Virtual para Treinamento em Visão de Máquina com LabVIEW "Esse ambiente pode ser usado para simular e explorar as possibilidades e alcances de uma solução empregando visão de máquina, testar

Leia mais

3.1 Definições Uma classe é a descrição de um tipo de objeto.

3.1 Definições Uma classe é a descrição de um tipo de objeto. Unified Modeling Language (UML) Universidade Federal do Maranhão UFMA Pós Graduação de Engenharia de Eletricidade Grupo de Computação Assunto: Diagrama de Classes Autoria:Aristófanes Corrêa Silva Adaptação:

Leia mais

APLICATIVOS GRÁFICOS (AULA 4)

APLICATIVOS GRÁFICOS (AULA 4) Prof. Breno Leonardo G. de M. Araújo brenod123@gmail.com http://blog.brenoleonardo.com.br APLICATIVOS GRÁFICOS (AULA 4) 1 Classificação da imagem Em relação à sua origem pode-se classificar uma imagem,

Leia mais

Manual do Usuário - ProJuris Web - Biblioteca Jurídica Página 1 de 20

Manual do Usuário - ProJuris Web - Biblioteca Jurídica Página 1 de 20 As informações contidas neste documento estão sujeitas a alterações sem o prévio aviso, o que não representa um compromisso da Virtuem Informática. As pessoas, organizações ou empresas e eventos de exemplos

Leia mais

Síntese de voz panorama tecnológico ANTONIO BORGES

Síntese de voz panorama tecnológico ANTONIO BORGES Síntese de voz panorama tecnológico ANTONIO BORGES Quase todos nós vamos precisar de óculos um dia (a menos que a tecnologia médica promova a substituição deste artefato por alguma outra coisa tecnológica,

Leia mais

Cálculo de volume de objetos utilizando câmeras RGB-D

Cálculo de volume de objetos utilizando câmeras RGB-D Cálculo de volume de objetos utilizando câmeras RGB-D Servílio Souza de ASSIS 1,3,4 ; Izadora Aparecida RAMOS 1,3,4 ; Bruno Alberto Soares OLIVEIRA 1,3 ; Marlon MARCON 2,3 1 Estudante de Engenharia de

Leia mais

Análise e Projeto de Software

Análise e Projeto de Software Análise e Projeto de Software 1 Mundo Real Modelagem Elicitação Análise Problemas Soluções Gap Semântico Mundo Computacional Elicitação de Requisitos Análise de Requisitos Modelagem dos Requisitos 2 Projeto

Leia mais

Programação em papel quadriculado

Programação em papel quadriculado 4 NOME DA AULA: Programação em papel quadriculado Tempo de aula: 45 60 minutos Tempo de preparação: 10 minutos Objetivo principal: ajudar os alunos a entender como a codificação funciona. RESUMO Ao "programar"

Leia mais

Estudo de técnicas de rastreamento de objetos aplicadas à detecção de múltiplas larvas

Estudo de técnicas de rastreamento de objetos aplicadas à detecção de múltiplas larvas Estudo de técnicas de rastreamento de objetos aplicadas à detecção de múltiplas larvas Guilherme de Oliveira Vicente Orientador: Prof. Dr. Hemerson Pistori Coorientador: Prof. Me. Kleber Padovani de Souza

Leia mais

Resolução da lista de exercícios de casos de uso

Resolução da lista de exercícios de casos de uso Resolução da lista de exercícios de casos de uso 1. Explique quando são criados e utilizados os diagramas de casos de uso no processo de desenvolvimento incremental e iterativo. Na fase de concepção se

Leia mais

Metadados. 1. Introdução. 2. O que são Metadados? 3. O Valor dos Metadados

Metadados. 1. Introdução. 2. O que são Metadados? 3. O Valor dos Metadados 1. Introdução O governo é um dos maiores detentores de recursos da informação. Consequentemente, tem sido o responsável por assegurar que tais recursos estejam agregando valor para os cidadãos, as empresas,

Leia mais

Classificação da imagem (ou reconhecimento de padrões): objectivos Métodos de reconhecimento de padrões

Classificação da imagem (ou reconhecimento de padrões): objectivos Métodos de reconhecimento de padrões Classificação de imagens Autor: Gil Gonçalves Disciplinas: Detecção Remota/Detecção Remota Aplicada Cursos: MEG/MTIG Ano Lectivo: 11/12 Sumário Classificação da imagem (ou reconhecimento de padrões): objectivos

Leia mais

Processamento digital de imagens. introdução

Processamento digital de imagens. introdução Processamento digital de imagens introdução Imagem digital Imagem digital pode ser descrita como uma matriz bidimensional de números inteiros que corresponde a medidas discretas da energia eletromagnética

Leia mais

Projeto de inovação do processo de monitoramento de safra da Conab

Projeto de inovação do processo de monitoramento de safra da Conab Projeto de inovação do processo de monitoramento de safra da Conab Projeto elaborado por Lorenzo Seguini lorenzo_seguini@yahoo.it Projeto Diálogos Setoriais União Europeia - Brasil 1 Sumário 1. Introdução...3

Leia mais

Optimização de um Mundo Virtual

Optimização de um Mundo Virtual secção 3.2 Optimização de um Mundo Virtual Dadas as limitações impostas pela actual tecnologia, um mundo virtual que não seja cuidadosamente optimizado torna-se necessariamente demasiado lento para captar

Leia mais

Oficina de Manipulação e Edição de Fotografia e Imagem Digital GIMP

Oficina de Manipulação e Edição de Fotografia e Imagem Digital GIMP Oficina de Manipulação e Edição de Fotografia e Imagem Digital GIMP O que é o GIMP É um programa de criação e edição de imagens. Foi criado como uma alternativa livre ao Photoshop, ou seja, é um software

Leia mais

Figura 5.1.Modelo não linear de um neurônio j da camada k+1. Fonte: HAYKIN, 2001

Figura 5.1.Modelo não linear de um neurônio j da camada k+1. Fonte: HAYKIN, 2001 47 5 Redes Neurais O trabalho em redes neurais artificiais, usualmente denominadas redes neurais ou RNA, tem sido motivado desde o começo pelo reconhecimento de que o cérebro humano processa informações

Leia mais

Aula 5 - Classificação

Aula 5 - Classificação AULA 5 - Aula 5-1. por Pixel é o processo de extração de informação em imagens para reconhecer padrões e objetos homogêneos. Os Classificadores "pixel a pixel" utilizam apenas a informação espectral isoladamente

Leia mais

Professor Paulo Lorini Najar

Professor Paulo Lorini Najar Microsoft PowerPoint O Microsoft PowerPoint é uma ferramenta ou gerador de apresentações, palestras, workshops, campanhas publicitárias, utilizados por vários profissionais, entre eles executivos, publicitários,

Leia mais

Superintendência Regional de Ensino de Ubá - MG Núcleo de Tecnologia Educacional NTE/Ubá. LibreOffice Impress Editor de Apresentação

Superintendência Regional de Ensino de Ubá - MG Núcleo de Tecnologia Educacional NTE/Ubá. LibreOffice Impress Editor de Apresentação Superintendência Regional de Ensino de Ubá - MG Núcleo de Tecnologia Educacional NTE/Ubá LibreOffice Impress Editor de Apresentação Iniciando o Impress no Linux Educacional 4 1. Clique no botão 'LE' no

Leia mais

ADMINISTRAÇÃO GERAL GESTÃO DE PROCESSOS

ADMINISTRAÇÃO GERAL GESTÃO DE PROCESSOS ADMINISTRAÇÃO GERAL GESTÃO DE PROCESSOS Atualizado em 21/12/2015 GESTÃO DE PROCESSOS Um processo é um conjunto ou sequência de atividades interligadas, com começo, meio e fim. Por meio de processos, a

Leia mais

Especificação Operacional.

Especificação Operacional. Especificação Operacional. Para muitos sistemas, a incerteza acerca dos requisitos leva a mudanças e problemas mais tarde no desenvolvimento de software. Zave (1984) sugere um modelo de processo que permite

Leia mais

c. Técnica de Estrutura de Controle Teste do Caminho Básico

c. Técnica de Estrutura de Controle Teste do Caminho Básico 1) Defina: a. Fluxo de controle A análise de fluxo de controle é a técnica estática em que o fluxo de controle através de um programa é analisado, quer com um gráfico, quer com uma ferramenta de fluxo

Leia mais

PROJETO DE COOPERAÇÃO TÉCNICA INTERNACIONAL. Projeto 914 BRA5065 - PRODOC-MTC/UNESCO DOCUMENTO TÉCNICO Nº 03

PROJETO DE COOPERAÇÃO TÉCNICA INTERNACIONAL. Projeto 914 BRA5065 - PRODOC-MTC/UNESCO DOCUMENTO TÉCNICO Nº 03 PROJETO DE COOPERAÇÃO TÉCNICA INTERNACIONAL Diretrizes e Estratégias para Ciência, Tecnologia e Inovação no Brasil Projeto 914 BRA5065 - PRODOC-MTC/UNESCO DOCUMENTO TÉCNICO Nº 03 RELATÓRIO TÉCNICO CONCLUSIVO

Leia mais

Portal do Projeto Tempo de Ser

Portal do Projeto Tempo de Ser Sumário Portal do Projeto Tempo de Ser O que é um Wiki?...2 Documentos...2 Localizando documentos...3 Links...3 Criando um Documento...4 Criando um link...4 Editando um Documento...5 Sintaxe Básica...5

Leia mais

INSTITUTO TECNOLÓGICO

INSTITUTO TECNOLÓGICO PAC - PROGRAMA DE APRIMORAMENTO DE CONTEÚDOS. ATIVIDADES DE NIVELAMENTO BÁSICO. DISCIPLINAS: MATEMÁTICA & ESTATÍSTICA. PROFº.: PROF. DR. AUSTER RUZANTE 1ª SEMANA DE ATIVIDADES DOS CURSOS DE TECNOLOGIA

Leia mais

Introdução. Capítulo. 1.1 Considerações Iniciais

Introdução. Capítulo. 1.1 Considerações Iniciais Capítulo 1 Introdução 1.1 Considerações Iniciais A face humana é uma imagem fascinante, serve de infinita inspiração a artistas há milhares de anos. Uma das primeiras e mais importantes habilidades humanas

Leia mais

Encontrando a Linha Divisória: Detecção de Bordas

Encontrando a Linha Divisória: Detecção de Bordas CAPÍTULO 1 Encontrando a Linha Divisória: Detecção de Bordas Contribuíram: Daniela Marta Seara, Geovani Cássia da Silva Espezim Elizandro Encontrar Bordas também é Segmentar A visão computacional envolve

Leia mais

agility made possible

agility made possible RESUMO DA SOLUÇÃO Utilitário ConfigXpress no CA IdentityMinder a minha solução de gerenciamento de identidades pode se adaptar rapidamente aos requisitos e processos de negócio em constante mudança? agility

Leia mais

MODELAGEM DE PROCESSOS USANDO BPMN (BUSINESS PROCESS MODEL AND NOTATION) E IOT (INTERNET DAS COISAS)

MODELAGEM DE PROCESSOS USANDO BPMN (BUSINESS PROCESS MODEL AND NOTATION) E IOT (INTERNET DAS COISAS) WHITE PAPPER Rafael Fazzi Bortolini Diretor, Cryo Technologies Orquestra BPMS rafael@cryo.com.br Internet das Coisas e Gerenciamento de Processos de Negócio (BPM) são duas disciplinas ou tendências à primeira

Leia mais

Fração como porcentagem. Sexto Ano do Ensino Fundamental. Autor: Prof. Francisco Bruno Holanda Revisor: Prof. Antonio Caminha M.

Fração como porcentagem. Sexto Ano do Ensino Fundamental. Autor: Prof. Francisco Bruno Holanda Revisor: Prof. Antonio Caminha M. Material Teórico - Módulo de FRAÇÕES COMO PORCENTAGEM E PROBABILIDADE Fração como porcentagem Sexto Ano do Ensino Fundamental Autor: Prof. Francisco Bruno Holanda Revisor: Prof. Antonio Caminha M. Neto

Leia mais

O Princípio da Complementaridade e o papel do observador na Mecânica Quântica

O Princípio da Complementaridade e o papel do observador na Mecânica Quântica O Princípio da Complementaridade e o papel do observador na Mecânica Quântica A U L A 3 Metas da aula Descrever a experiência de interferência por uma fenda dupla com elétrons, na qual a trajetória destes

Leia mais

Frederico Damasceno Bortoloti. Adaptado de: Claudio Esperança Paulo Roma Cavalcanti

Frederico Damasceno Bortoloti. Adaptado de: Claudio Esperança Paulo Roma Cavalcanti Fundamentos de Representação Gráfica Frederico Damasceno Bortoloti Adaptado de: Claudio Esperança Paulo Roma Cavalcanti Estrutura do Curso Avaliação através de Prova Estudo / Seminário Nota parcial NP

Leia mais

Aula 4 Conceitos Básicos de Estatística. Aula 4 Conceitos básicos de estatística

Aula 4 Conceitos Básicos de Estatística. Aula 4 Conceitos básicos de estatística Aula 4 Conceitos Básicos de Estatística Aula 4 Conceitos básicos de estatística A Estatística é a ciência de aprendizagem a partir de dados. Trata-se de uma disciplina estratégica, que coleta, analisa

Leia mais

OpenGL. Uma Abordagem Prática e Objetiva. Marcelo Cohen Isabel Harb Manssour. Novatec Editora

OpenGL. Uma Abordagem Prática e Objetiva. Marcelo Cohen Isabel Harb Manssour. Novatec Editora OpenGL Uma Abordagem Prática e Objetiva Marcelo Cohen Isabel Harb Manssour Novatec Editora Capítulo 1 Introdução A Computação Gráfica é uma área da Ciência da Computação que se dedica ao estudo e ao desenvolvimento

Leia mais

UNIVERSIDADE FEDERAL RURAL DE PERNAMBUCO DEPARTAMENTO DE ESTATÍSTICA E INFORMÁTICA BACHARELADO EM SISTEMAS DE INFORMAÇÃO RAPID APPLICATION DEVELOPMENT

UNIVERSIDADE FEDERAL RURAL DE PERNAMBUCO DEPARTAMENTO DE ESTATÍSTICA E INFORMÁTICA BACHARELADO EM SISTEMAS DE INFORMAÇÃO RAPID APPLICATION DEVELOPMENT UNIVERSIDADE FEDERAL RURAL DE PERNAMBUCO DEPARTAMENTO DE ESTATÍSTICA E INFORMÁTICA BACHARELADO EM SISTEMAS DE INFORMAÇÃO RAPID APPLICATION DEVELOPMENT Disciplina: Modelagem a Programação Orientada a Objetos

Leia mais

AMOSTRAGEM ESTATÍSTICA EM AUDITORIA PARTE ll

AMOSTRAGEM ESTATÍSTICA EM AUDITORIA PARTE ll AMOSTRAGEM ESTATÍSTICA EM AUDITORIA PARTE ll! Os parâmetros para decisão do auditor.! Tipos de planos de amostragem estatística em auditoria. Francisco Cavalcante(f_c_a@uol.com.br) Administrador de Empresas

Leia mais

BIBLIOTECA PARA ANÁLISE DE DADOS EM IMAGENS ESTEREOSCÓPICAS

BIBLIOTECA PARA ANÁLISE DE DADOS EM IMAGENS ESTEREOSCÓPICAS BIBLIOTECA PARA ANÁLISE DE DADOS EM IMAGENS ESTEREOSCÓPICAS Aluno: Ricardo I Salvador Orientador: Marcel Hugo Roteiro Introdução à biblioteca Objetivo da biblioteca Fundamentação Teórica Trabalhos Correlatos

Leia mais

3 Qualidade de Software

3 Qualidade de Software 3 Qualidade de Software Este capítulo tem como objetivo esclarecer conceitos relacionados à qualidade de software; conceitos estes muito importantes para o entendimento do presente trabalho, cujo objetivo

Leia mais

AULA 2 Planos, Vistas e Temas

AULA 2 Planos, Vistas e Temas 2.1 AULA 2 Planos, Vistas e Temas Essa aula apresenta os conceitos de Plano de Informação, Vista e Tema e suas manipulações no TerraView. Para isso será usado o banco de dados criado na AULA 1. Abra o

Leia mais

4 Segmentação. 4.1. Algoritmo proposto

4 Segmentação. 4.1. Algoritmo proposto 4 Segmentação Este capítulo apresenta primeiramente o algoritmo proposto para a segmentação do áudio em detalhes. Em seguida, são analisadas as inovações apresentadas. É importante mencionar que as mudanças

Leia mais

Relatório Trabalho Prático 2 : Colônia de Formigas para Otimização e Agrupamento

Relatório Trabalho Prático 2 : Colônia de Formigas para Otimização e Agrupamento Relatório Trabalho Prático 2 : Colônia de Formigas para Otimização e Agrupamento Ramon Pereira Lopes Rangel Silva Oliveira 31 de outubro de 2011 1 Introdução O presente documento refere-se ao relatório

Leia mais

18º Congresso de Iniciação Científica IMPLEMENTAÇÃO DE UM MODELO DE TESTE DE APLICAÇÕES WEB

18º Congresso de Iniciação Científica IMPLEMENTAÇÃO DE UM MODELO DE TESTE DE APLICAÇÕES WEB 18º Congresso de Iniciação Científica IMPLEMENTAÇÃO DE UM MODELO DE TESTE DE APLICAÇÕES WEB Autor(es) HARLEI MIGUEL DE ARRUDA LEITE Orientador(es) PLÍNIO ROBERTO SOUZA VILELA Apoio Financeiro PIBIC/CNPQ

Leia mais

Capítulo 5: Aplicações da Derivada

Capítulo 5: Aplicações da Derivada Instituto de Ciências Exatas - Departamento de Matemática Cálculo I Profª Maria Julieta Ventura Carvalho de Araujo Capítulo 5: Aplicações da Derivada 5- Acréscimos e Diferenciais - Acréscimos Seja y f

Leia mais

Bruno Pereira Evangelista. www.brunoevangelista.com

Bruno Pereira Evangelista. www.brunoevangelista.com Bruno Pereira Evangelista www.brunoevangelista.com 2 Introdução Shaders Pipeline de Renderização Evolução dos Shaders Como Programar Shaders Programando Shaders com XNA Ferramentas Conclusões 3 Durante

Leia mais

Unidade 5: Sistemas de Representação

Unidade 5: Sistemas de Representação Arquitetura e Organização de Computadores Atualização: 9/8/ Unidade 5: Sistemas de Representação Números de Ponto Flutuante IEEE 754/8 e Caracteres ASCII Prof. Daniel Caetano Objetivo: Compreender a representação

Leia mais

6 Ferramenta de Apoio ao Processo de Desenvolvimento de Sistemas Multi-Agentes

6 Ferramenta de Apoio ao Processo de Desenvolvimento de Sistemas Multi-Agentes 6 Ferramenta de Apoio ao Processo de Desenvolvimento de Sistemas Multi-Agentes A ferramenta MAS-ML Tool surgiu com o objetivo de viabilizar o processo de desenvolvimento proposto na Seção anterior, implementando

Leia mais

Capítulo 2. Processos de Software. 2011 Pearson Prentice Hall. Todos os direitos reservados. slide 1

Capítulo 2. Processos de Software. 2011 Pearson Prentice Hall. Todos os direitos reservados. slide 1 Capítulo 2 Processos de Software slide 1 Tópicos apresentados Modelos de processo de software. Atividades de processo. Lidando com mudanças. Rational Unified Process (RUP). Um exemplo de um processo de

Leia mais

Computador E/S, Memória, Barramento do sistema e CPU Onde a CPU Registradores, ULA, Interconexão interna da CPU e Unidade de controle.

Computador E/S, Memória, Barramento do sistema e CPU Onde a CPU Registradores, ULA, Interconexão interna da CPU e Unidade de controle. Introdução Os principais elementos de um sistema de computação são a unidade central de processamento (central processing unit CPU), a memória principal, o subsistema de E/S (entrada e saída) e os mecanismos

Leia mais

Segmentação de Imagens

Segmentação de Imagens Segmentação de Imagens (Processamento Digital de Imagens) 1 / 36 Fundamentos A segmentação subdivide uma imagem em regiões ou objetos que a compõem; nível de detalhe depende do problema segmentação para

Leia mais

Top Guia In.Fra: Perguntas para fazer ao seu fornecedor de CFTV

Top Guia In.Fra: Perguntas para fazer ao seu fornecedor de CFTV Top Guia In.Fra: Perguntas para fazer ao seu fornecedor de CFTV 1ª Edição (v1.4) 1 Um projeto de segurança bem feito Até pouco tempo atrás o mercado de CFTV era dividido entre fabricantes de alto custo

Leia mais

Seguro-Saúde. Guia para Consulta Rápida

Seguro-Saúde. Guia para Consulta Rápida Seguro-Saúde. Guia para Consulta Rápida O que é seguro? 6 O que é Seguro-Saúde? 6 Como são os contratos de Seguro-Saúde? 7 Como ficaram as apólices antigas depois da Lei nº 9656/98? 8 Qual a diferença

Leia mais

Processos de gerenciamento de projetos em um projeto

Processos de gerenciamento de projetos em um projeto Processos de gerenciamento de projetos em um projeto O gerenciamento de projetos é a aplicação de conhecimentos, habilidades, ferramentas e técnicas às atividades do projeto a fim de cumprir seus requisitos.

Leia mais

Medindo a Produtividade do Desenvolvimento de Aplicativos

Medindo a Produtividade do Desenvolvimento de Aplicativos Medindo a Produtividade do Desenvolvimento de Aplicativos Por Allan J. Albrecht Proc. Joint SHARE/GUIDE/IBM Application Development Symposium (October, 1979), 83-92 IBM Corporation, White Plains, New York

Leia mais

Sumário INTRODUÇÃO 3 TELA DE APRESENTAÇÃO 3 DESENHANDO E TRANSFORMANDO 29 FERRAMENTA FORMA 29 PREENCHIMENTOS E CONTORNOS 36

Sumário INTRODUÇÃO 3 TELA DE APRESENTAÇÃO 3 DESENHANDO E TRANSFORMANDO 29 FERRAMENTA FORMA 29 PREENCHIMENTOS E CONTORNOS 36 Sumário Todos os direitos reservados e protegidos pela Lei 5.988 de 14/12/73. Nenhuma parte deste livro, sem prévia autorização por escrito de Celta Informática, poderá ser reproduzida total ou parcialmente,

Leia mais

Gerenciamento da Integração (PMBoK 5ª ed.)

Gerenciamento da Integração (PMBoK 5ª ed.) Gerenciamento da Integração (PMBoK 5ª ed.) O PMBoK diz que: O gerenciamento da integração do projeto inclui os processos e as atividades necessárias para identificar, definir, combinar, unificar e coordenar

Leia mais

1 Introdução. Componentes Usuários. Provedor de Serviços. Figura 1.1 Ambiente de oferecimento de serviços

1 Introdução. Componentes Usuários. Provedor de Serviços. Figura 1.1 Ambiente de oferecimento de serviços 1 Introdução Nos últimos anos, houve um aumento notável de demanda por plataformas com suporte a diferentes mídias. Aplicações manipulando simultaneamente texto, vídeo e áudio são cada vez mais comuns.

Leia mais

Manual do Usuário. Protocolo

Manual do Usuário. Protocolo Manual do Usuário Protocolo Índice de capítulos Parte I - Processos............................... 01 1 - Buscar................................ 01 2 - Listar................................ 02 3 - Abertura..............................

Leia mais

Manual de Utilizador. Caderno. Recursos da Unidade Curricular. Gabinete de Ensino à Distância do IPP. http://eweb.ipportalegre.pt. ged@ipportalegre.

Manual de Utilizador. Caderno. Recursos da Unidade Curricular. Gabinete de Ensino à Distância do IPP. http://eweb.ipportalegre.pt. ged@ipportalegre. Manual de Utilizador Caderno Recursos da Unidade Curricular Gabinete de Ensino à Distância do IPP http://eweb.ipportalegre.pt ged@ipportalegre.pt Índice RECURSOS... 1 ADICIONAR E CONFIGURAR RECURSOS...

Leia mais

A educadora avalia a formação de nossos professores para o ensino da Matemática e os caminhos para trabalhar a disciplina na Educação Infantil.

A educadora avalia a formação de nossos professores para o ensino da Matemática e os caminhos para trabalhar a disciplina na Educação Infantil. Matemática na Educação Infantil: é possível A educadora avalia a formação de nossos professores para o ensino da Matemática e os caminhos para trabalhar a disciplina na Educação Infantil. Nas avaliações

Leia mais

O ENSINO DE CÁLCULO NUMÉRICO: UMA EXPERIÊNCIA COM ALUNOS DO CURSO DE CIÊNCIA DA COMPUTAÇÃO

O ENSINO DE CÁLCULO NUMÉRICO: UMA EXPERIÊNCIA COM ALUNOS DO CURSO DE CIÊNCIA DA COMPUTAÇÃO O ENSINO DE CÁLCULO NUMÉRICO: UMA EXPERIÊNCIA COM ALUNOS DO CURSO DE CIÊNCIA DA COMPUTAÇÃO Prof. Leugim Corteze Romio Universidade Regional Integrada URI Campus Santiago-RS leugimcr@urisantiago.br Prof.

Leia mais

A SEGUIR ALGUMAS DICAS PARA O DESENVOLVIMENTO DE UM PROJETO CIENTÍFICO

A SEGUIR ALGUMAS DICAS PARA O DESENVOLVIMENTO DE UM PROJETO CIENTÍFICO A SEGUIR ALGUMAS DICAS PARA O DESENVOLVIMENTO DE UM PROJETO CIENTÍFICO DESENVOLVENDO UM PROJETO 1. Pense em um tema de seu interesse ou um problema que você gostaria de resolver. 2. Obtenha um caderno

Leia mais

IMPLEMENTAÇÃO DE UM SISTEMA DE SELEÇÃO DE PEÇA USANDO CONCEITOS DE PROGRAMAÇÃO DE SISTEMA DE AUTOMAÇÃO. João Alvarez Peixoto*

IMPLEMENTAÇÃO DE UM SISTEMA DE SELEÇÃO DE PEÇA USANDO CONCEITOS DE PROGRAMAÇÃO DE SISTEMA DE AUTOMAÇÃO. João Alvarez Peixoto* IMPLEMENTAÇÃO DE UM SISTEMA DE SELEÇÃO DE PEÇA USANDO CONCEITOS DE PROGRAMAÇÃO DE SISTEMA DE AUTOMAÇÃO João Alvarez Peixoto* * Mestrando do Programa de Pós-graduação em Engenharia Elétrica - UFRGS Porto

Leia mais

Faculdade Sagrada Família

Faculdade Sagrada Família AULA 12 - AJUSTAMENTO DE CURVAS E O MÉTODO DOS MÍNIMOS QUADRADOS Ajustamento de Curvas Sempre que desejamos estudar determinada variável em função de outra, fazemos uma análise de regressão. Podemos dizer

Leia mais

PONTIFÍCIA UNIVERSIDADE CATÓLICA DO RIO DE JANEIRO DEPARTAMENTO DE INFORMÁTICA PÓS GRADUAÇÃO EM INFORMÁTICA

PONTIFÍCIA UNIVERSIDADE CATÓLICA DO RIO DE JANEIRO DEPARTAMENTO DE INFORMÁTICA PÓS GRADUAÇÃO EM INFORMÁTICA PONTIFÍCIA UNIVERSIDADE CATÓLICA DO RIO DE JANEIRO DEPARTAMENTO DE INFORMÁTICA PÓS GRADUAÇÃO EM INFORMÁTICA INF2608 FUNDAMENTOS DE COMPUTAÇÃO GRÁFICA RELATÓRIO: IMAGENS SÍSMICAS VISUALIZAÇÃO E DETECÇÃO

Leia mais

2 Ferramentas Utilizadas

2 Ferramentas Utilizadas 2 Ferramentas Utilizadas Esta dissertação utiliza vários outros trabalhos para implementar os mecanismos de adaptação abordados. Essas ferramentas são descritas nas seções seguintes. 2.1 Lua Lua [7, 8]

Leia mais

Prática 19 e 20 Características de um bom jogo

Prática 19 e 20 Características de um bom jogo Prática 19 e 20 Características de um bom jogo 1. Objetivos Estudar os elementos essenciais no desenvolvimento de jogos Desenvolver um jogo em Flash 2. Recursos Necessários Computador com o programa Macromedia

Leia mais

Medição tridimensional

Medição tridimensional A U A UL LA Medição tridimensional Um problema O controle de qualidade dimensional é tão antigo quanto a própria indústria, mas somente nas últimas décadas vem ocupando a importante posição que lhe cabe.

Leia mais

Maya Live. M aya. por Gustavo L. Braga

Maya Live. M aya. por Gustavo L. Braga M aya por Gustavo L. Braga Maya Live Quando fazemos uma animação de algum elemento virtual que deve ser aplicado a uma cena capturada, temos o grande desafio de ambientar este elemento na cena. Este desafio,

Leia mais

APOSTILA DE EXEMPLO (Esta é só uma reprodução parcial do conteúdo)

APOSTILA DE EXEMPLO (Esta é só uma reprodução parcial do conteúdo) APOSTILA DE EXEMPLO (Esta é só uma reprodução parcial do conteúdo) 1 Índice Aula 1...3 Introdução... 3 Formatações de tabela... 4 Função HOJE... 6 Função SE... 6 Exercícios... 7 Exercício de Fixação...

Leia mais

UNIVERSIDADE FEDERAL DE SANTA MARIA CENTRO DE TECNOLOGIA AULA 14 PROFª BRUNO CALEGARO

UNIVERSIDADE FEDERAL DE SANTA MARIA CENTRO DE TECNOLOGIA AULA 14 PROFª BRUNO CALEGARO UNIVERSIDADE FEDERAL DE SANTA MARIA CENTRO DE TECNOLOGIA AULA 14 PROFª BRUNO CALEGARO Santa Maria, 01 de Novembro de 2013. Revisão aula passada Projeto de Arquitetura Decisões de projeto de Arquitetura

Leia mais

VIII Semana de Ciência e Tecnologia IFMG campus Bambuí VIII Jornada Científica TECLADO VIRTUAL ACESSÍVEL PARA SMARTPHONES E TABLETS

VIII Semana de Ciência e Tecnologia IFMG campus Bambuí VIII Jornada Científica TECLADO VIRTUAL ACESSÍVEL PARA SMARTPHONES E TABLETS TECLADO VIRTUAL ACESSÍVEL PARA SMARTPHONES E TABLETS Daniele Nazaré Tavares¹; Daniela Costa Terra² ¹Estudante de Engenharia da Computação. Instituto Federal Minas Gerais (IFMG) campus Bambuí. Rod. Bambuí/Medeiros

Leia mais

Sumário. 1. Instalando a Chave de Proteção 3. 2. Novas características da versão 1.3.8 3. 3. Instalando o PhotoFacil Álbum 4

Sumário. 1. Instalando a Chave de Proteção 3. 2. Novas características da versão 1.3.8 3. 3. Instalando o PhotoFacil Álbum 4 1 Sumário 1. Instalando a Chave de Proteção 3 2. Novas características da versão 1.3.8 3 3. Instalando o PhotoFacil Álbum 4 4. Executando o PhotoFacil Álbum 9 3.1. Verificação da Chave 9 3.1.1. Erro 0001-7

Leia mais

Aula 9 ESCALA GRÁFICA. Antônio Carlos Campos

Aula 9 ESCALA GRÁFICA. Antônio Carlos Campos Aula 9 ESCALA GRÁFICA META Apresentar as formas de medição da proporcionalidade entre o mundo real e os mapas através das escalas gráficas. OBJETIVOS Ao final desta aula, o aluno deverá: estabelecer formas

Leia mais

Trabalho de Implementação Jogo Reversi

Trabalho de Implementação Jogo Reversi Trabalho de Implementação Jogo Reversi Paulo Afonso Parreira Júnior {paulojr@comp.ufla.br} Rilson Machado de Olivera {rilson@comp.ufla.br} Universidade Federal de Lavras UFLA Departamento de Ciência da

Leia mais

Engenharia de Software e Gerência de Projetos Prof. Esp. André Luís Belini Bacharel em Sistemas de Informações MBA em Gestão Estratégica de Negócios

Engenharia de Software e Gerência de Projetos Prof. Esp. André Luís Belini Bacharel em Sistemas de Informações MBA em Gestão Estratégica de Negócios Engenharia de Software e Gerência de Projetos Prof. Esp. André Luís Belini Bacharel em Sistemas de Informações MBA em Gestão Estratégica de Negócios Cronograma das Aulas. Hoje você está na aula Semana

Leia mais

4 Avaliação Experimental

4 Avaliação Experimental 4 Avaliação Experimental Este capítulo apresenta uma avaliação experimental dos métodos e técnicas aplicados neste trabalho. Base para esta avaliação foi o protótipo descrito no capítulo anterior. Dentre

Leia mais

Desenvolvimento de uma Etapa

Desenvolvimento de uma Etapa Desenvolvimento de uma Etapa A Fase Evolutiva do desenvolvimento de um sistema compreende uma sucessão de etapas de trabalho. Cada etapa configura-se na forma de um mini-ciclo que abrange as atividades

Leia mais

TRANSIÇÃO DAS CERTIFICAÇÕES DOS SISTEMAS DE GESTÃO DA QUALIDADE E SISTEMAS DE GESTÃO AMBIENTAL, PARA AS VERSÕES 2015 DAS NORMAS.

TRANSIÇÃO DAS CERTIFICAÇÕES DOS SISTEMAS DE GESTÃO DA QUALIDADE E SISTEMAS DE GESTÃO AMBIENTAL, PARA AS VERSÕES 2015 DAS NORMAS. TRANSIÇÃO DAS CERTIFICAÇÕES DOS SISTEMAS DE GESTÃO DA QUALIDADE E SISTEMAS DE GESTÃO AMBIENTAL, PARA AS VERSÕES 2015 DAS NORMAS. As novas versões das normas ABNT NBR ISO 9001 e ABNT NBR ISO 14001 foram

Leia mais

Banco de Dados Espaciais. Banco de Dados Espaciais

Banco de Dados Espaciais. Banco de Dados Espaciais Banco de Dados Espaciais Henrique Cota Camêllo Banco de Dados Espaciais Sua estrutura de funcionamento é semelhante a dos bancos relacionais convencionais. Sua principal diferença é suportar feições geométricas

Leia mais

ELABORAÇÃO E ADMINISTRAÇÃO DE PROJETOS AULA 01: CONCEITOS BÁSICOS RELACIONADOS A PROJETOS TÓPICO 04: NECESSIDADE DE UMA AVALIAÇÃO ECONÔMICO-FINANCEIRA 1.14 NECESSIDADE DE UMA AVALIAÇÃO ECONÔMICO-FINANCEIRA

Leia mais

Preparação do Trabalho de Pesquisa

Preparação do Trabalho de Pesquisa Preparação do Trabalho de Pesquisa Ricardo de Almeida Falbo Metodologia de Pesquisa Departamento de Informática Universidade Federal do Espírito Santo Pesquisa Bibliográfica Etapas do Trabalho de Pesquisa

Leia mais

Os Tempos da Máquina. Gabriel Menotti

Os Tempos da Máquina. Gabriel Menotti Os Tempos da Máquina Gabriel Menotti A parte mais evidente das Máquinas do Tempo são as fotografias. É por meio desses elementos que o projeto de Andrei Thomaz se dá prontamente ao olhar. Um público acostumado

Leia mais

Unidade I - Fundamentos I.1 Introdução à Computação Gráfica

Unidade I - Fundamentos I.1 Introdução à Computação Gráfica Unidade I - Fundamentos I.1 Introdução à Computação Gráfica I.1.1 Introdução Começou com Exibição de informação para plotters Telas de tubos de raios catódicos (CRT) Tem se desenvolvido Criação, armazenamento

Leia mais

O Gerenciamento de Documentos Analógico/Digital

O Gerenciamento de Documentos Analógico/Digital Tipos de GED: Document imaging Document management Document Imaging / Document Management O Gerenciamento de Documentos Analógico/Digital Mundo analógico Criação Revisão Processamento Arquivo Mundo digital

Leia mais

4Distribuição de. freqüência

4Distribuição de. freqüência 4Distribuição de freqüência O objetivo desta Unidade é partir dos dados brutos, isto é, desorganizados, para uma apresentação formal. Nesse percurso, seção 1, destacaremos a diferença entre tabela primitiva

Leia mais