• Nenhum resultado encontrado

2010.2MonografiaMarcus Vinicius

N/A
N/A
Protected

Academic year: 2021

Share "2010.2MonografiaMarcus Vinicius"

Copied!
58
0
0

Texto

(1)

UNIVERSIDADE ESTADUAL DE FEIRA DE SANTANA

Marcus Vinicius Araujo Martins

APLICAÇÃO DE ALGORITMOS DE SUAVIZAÇÃO EM VOLUMES DE

IMAGENS UTILIZANDO A ARQUITETURA PARALELA OPENCL

FEIRA DE SANTANA 2010

(2)

MARCUS VINICIUS ARAUJO MARTINS

APLICAÇÃO DE ALGORITMOS DE SUAVIZAÇÃO EM VOLUMES DE

IMAGENS UTILIZANDO A ARQUITETURA PARALELA OPENCL

Trabalho de Conclusão de Curso apresentado ao curso de Graduação em Engenharia de Computação da Universidade Estadual de Feira de Santana para a obtenção do título de Bacharel em Engenharia de Computação

Orientador: Prof. Claudio Eduardo Góes

FEIRA DE SANTANA 2010

(3)

Resumo

Este trabalho apresenta a implementação de processamento de imagens médicas utilizando computação paralela. O processamento de imagens do tipo médicas tende a melhorar o diagnóstico, pois eliminam ruídos da imagem e a classifica. A idéia de utilizar computação paralela ocorre por duas motivações: a primeira decorre do fato de que o processamento de imagem tende a ser uma tarefa custosa em tempo de processamento, o que pode comprometer o desempenho da mesma na interação com o usuário, a depender do tipo de aplicação. A segunda motivação ocorre devido ao processamento sobre a base de dados não apresentar grandes dificuldades de ser paralelizado, uma vez que o processamento é igual para todo o volume. A idéia de computação paralela, aqui nesse projeto, utiliza o framework OpenCL e a tecnologia GPU presente em diversas placas de vídeo. A base de dados utilizada corresponde a volumes de imagens médicas de tomografia computadorizada. O objetivo é, portanto, paralelizar a tarefa de suavização de volumes de imagens, utilizando para isso o framework

OpenCL.

(4)

Abstract

This paper presents the implementation of medical image processing using Parallel Computing. The type of image processing tends to improve medical diagnosis by eliminating noise from the image and classifies it. The idea of using parallel computing is for two reasons: The first stems from the fact that the image processing tends to be a costly in processing time, which can compromise, depending on the type of application, its performance in user interaction. The second motivation is due to processing on the database does not present major difficulties to be parallelized, since the processing is equal to the entire volume. The idea of parallel computing, here in this project uses the framework OpenCL and GPU technology that appeared in several video cards. The database used corresponds to volumes of medical imaging and computed tomography. The goal is therefore parallel with the task of smoothing volumes of images, using, for this, the framework OpenCL.

(5)

SUMÁRIO

1 INTRODUÇÃO ... 5

2 FUNDAMENTAÇÃO TEÓRICA ... 7

2.1PROCESSAMENTODEIMAGENSDIGITAIS ... 7

2.1.1 Aquisição de imagens ... 9

2.1.1.1 Tomografia Computadorizada ... 10

2.1.2 Ruídos ... 11

2.1.3 Filtragem de imagens ... 13

2.2VISUALIZAÇÃOVOLUMÉTRICAETÉCNICASDEVISUALIZAÇÃO ... 16

2.2.1 Visualização através de superfícies ... 19

2.2.2 Visualização direta de volume ... 20

2.2.2.1 O algoritmo de Ray Casting ... 21

2.3–HARDWAREESPECÍFICO ... 23

2.4–COMPUTAÇÃOPARALELAEATAXONOMIADEFLYNN ... 24

2.5–OFRAMEWORKOPENCL... 27

2.5.1– A API OpenCL ... 27

2.5.2– Arquitetura OpenCL ... 29

3 METODOLOGIA ... 33

3.1SOFTWARE E HARDWAREUTILIZADOS ... 33

3.2DECISÕESDEPROJETO ... 34

3.3IMPLEMENTAÇÃO ... 36

3.3.1– Implementação do lado do Host ... 38

3.3.2– Implementação do lado do Kernel ... 42

4 RESULTADOS ... 45

5 CONCLUSÕES ... 51

REFERÊNCIAS ... 53

(6)

1 INTRODUÇÃO

A aplicabilidade da computação gráfica é notória em diversas áreas. Existem técnicas de processamento gráfico desde fotografar placas de carros em alta velocidade das estradas, que precisam de tratamento para foco das letras e números da placa, ao campo da arte, nos desenhos matriciais que precisam ser vetorizados. Todavia, ainda surgem necessidades de áreas distintas, que carecem de recursos da computação gráfica.

Como exemplo, a área científica e médica têm ganhado espaço em um dos campos da computação gráfica conhecida como visualização volumétrica. Não são raras as necessidades onde é preciso visualizar um comportamento de um líquido viscoso e simular sua vazão em tubos de aço que datam de muitos anos. Em outros casos, a medicina precisa de visualização volumétrica para detectar estruturas estranhas no organismo humano, como calcificações ou nódulos.

O princípio da visualização volumétrica é aproximar a realidade do virtual. O aumento de detalhes e recursos de iluminação são artifícios utilizados para tal aproximação. Não obstante, o aprimoramento desses recursos é bem visto para todas as áreas que carecem de simulação de dados e processamento tridimensional. Para os que usufruem da visualização volumétrica no lazer e no entretenimento, em jogos e animações, alcança-se um retorno na satisfação do usuário, na idéia de permitir mais realidade nos jogos e filmes. Na área médica, profissionais conseguem melhores diagnósticos à medida que o nível de detalhes aumenta, viabilizando uma melhoria na interação com o usuário.

Assim como qualquer avanço de software, existe um limite no aperfeiçoamento dos códigos ou utilização de algoritmos mais aprimorados, em que já não fornecem repostas tão satisfatórias. O processo de visualização volumétrica é uma tarefa custosa computacionalmente, principalmente quando os detalhes são bastante considerados. Alternativas de hardware se mostram possíveis no cotidiano, o que repercute diretamente em como os códigos devem ser implementados.

Muitos dos algoritmos de construção de volumes podem ser facilmente paralelizados. Nesse sentido, a utilização de hardware dedicado ou o uso de computação paralela se mostram atraentes quando se busca otimização nos detalhes e na velocidade de resposta da visualização. Todavia, o sentido que será aplicado aqui envolve a aplicação de algoritmos paralelizados para a atenuação de ruídos em imagens tomográficas, e não da construção do

(7)

volume como um todo. Assim, a visualização volumétrica tende a ser mais clara quando a base de dados considerada é pré-processada, isto é, distorções e ruídos são amenizados por algum processo de suavização na imagem, por exemplo.

O objetivo dessa pesquisa é atenuar ruídos em volumes de imagens utilizando filtros no domínio espacial. Deste modo, pode-se estender na idéia de aplicar tais filtros de forma paralela, utilizando para isso o framework OpenCL. Projeta-se então explorar a potencialidade da paralelização traçando comparativos entre códigos seriais e paralelos, ao passo que busca-se compreender como os algoritmos de amenização de ruídos funcionam. Busca-busca-se aplicar um recurso disponibilizado em muitos computadores de uso geral, que é a presença de núcleos GPU, discutidos nesse relatório, e que ainda não possui um acervo de aplicações que o utilizem.

A importância desse trabalho se evidencia principalmente na escassez de pesquisas relacionadas, ainda mais quando considera-se a ferramenta OpenCL como objeto de estudo. Técnicas de processamento de imagens em eliminação de ruídos são vistos em diversos trabalhos científicos e em aplicações diversas, como em ferramentas de edição de imagens. Porém, aplicações que envolvam a tecnologia OpenCL são ainda muito poucas.

O relato deste trabalho está dividido em: Fundamentação Teórica, definido na Seção 2, Metodologia, na Seção 3, Resultados, na Seção 4 e Considerações Finais, na seção 5. Na Fundamentação Teórica, alguns conceitos de processamento digital de imagens são apresentados, envolvendo aquisição e filtragem de imagens digitais. Além disso, é feita uma abordagem sobre visualização volumétrica e sobre hardwares específicos que estão associados à construção de volumes. Ainda nessa seção, conceitua-se a computação paralela apresentando a taxonomia de Flynn para a arquitetura de computadores. A seção se finda numa descrição do framework OpenCL, utilizado na paralelização do processamento do volume. A seção 3 trata da Metodologia, contendo o processo de instalação de drivers e

software e a as decisões de projeto. A etapa de implementação também é descrita nessa seção.

(8)

2 FUNDAMENTAÇÃO TEÓRICA

Nessa seção serão abordados alguns conceitos pertinentes ao desenvolvimento do projeto proposto.

2.1 PROCESSAMENTO DE IMAGENS DIGITAIS

O processamento digital de Imagens (PDI) existe no propósito de extrair informações importantes de um conjunto de dados através da melhoria da qualidade da imagem pelo realce das suas estruturas. Tal realce se faz necessário por diversos motivos, que vão desde a uma imagem que possui distorções, por datarem de longas épocas, por exemplo, até necessidades de cunho da arte, onde a qualidade das fotografias precisa ser alcançada ao máximo.

Não obstante, as áreas que carecem dessa tecnologia são várias: A geografia utiliza PDI na digitalização de mapas, em especial quando precisa diferenciar estruturas reais daquelas que podem ter sido rasuras do mapa original, tal qual a digitalização foi feita. Na área médica, sua aplicação é especial para um bom diagnóstico que tem como bases Raios X e Ressonância Magnética (MRI).

Imagens digitais e, por sua vez, também o PDI, trabalham com a representação matricial. Neste esquema, cada elemento da matriz é chamado de pixel. Para uma imagem monocromática, por exemplo, cada pixel possui uma variação de 256 possibilidades de tons de cinza, que vão do 0, preto, ao 255, branco. A Figura 1(a) apresenta uma imagem em tons de cinza e a Figura1(b), a sua representação matricial em valores entre 0 e 255. A Figura 1(c) representa apenas a linearização dos valores apresentados na Figura 1(b).

Figura 1 – Figura 2 – Representação de uma imagem em tons de cinza em valores discretos. a)Imagem b)Matriz com valores discretos c) Representação seqüencial

(9)

Uma imagem digital, tal qual a representação da Figura 1(b), do tipo bidimensional (2D), pode ser definida como uma função de duas dimensões, f(x,y), e tendo cada par de coordenadas uma intensidade discreta finita (GONZALES; WOODS, 2002). Numa visualização tridimensional (3D), uma nova coordenada existe, a coordenada z, que corresponde, em imagens tomográficas, a quantidade de imagens 2D sobrepostas. Assim, uma imagem 3D é uma função de três variáveis, f(x,y,z), como mostrado na Figura 2.

Figura 2 – Matriz tridimensional (Fonte: próprio autor)

O PDI é normalmente dividido em três etapas: pré-processamento, realce e classificação. Na primeira etapa, pré-processamento, os dados brutos são ajustados, o que engloba corrigir distorções, provenientes de uma má aquisição da imagem, e remover ruídos, apresentados na seção 2.1.2. A segunda etapa, realce, inclui melhorar a qualidade da imagem, permitindo uma maior distinção entre os objetos visíveis na imagem. Técnicas pertinentes a essa etapa são: realce de contraste, filtragem, operações aritméticas, como subtração e multiplicação de imagens, dentre outras. Na terceira etapa, classificação, são definidos grupos aos objetos visíveis na imagem. Essa etapa é relativa à aplicação, tal como mapear uma imagem médica, colorindo, por exemplo, em vermelho, regiões musculares ou, em imagens geográficas, anular regiões terrestres, quando o objetivo é focar no estudo de correntes marítimas e não sendo importante o mapeamento de terras.

Este trabalho apresenta uma abordagem sobre filtragem de imagens médicas 3D, no intuito de eliminar ruídos. Um estudo focalizado sobre o conceito de ruídos e suas classificações é encontrado na seção 2.1.2 e conceitos e aplicações referentes à filtragem pode ser visto na seção 2.1.3.

(10)

2.1.1 Aquisição de imagens

Para se obter uma imagem digital, são necessários dois elementos: dispositivos físicos captadores de imagens e digitalizadores (LAGEMANN, 2007). Dispositivos físicos possuem a propriedade de serem sensíveis a uma determinada faixa de energia eletromagnética (luz). Uma vez sendo detectada tal energia, é papel do digitalizador converter o sinal físico num sinal digital correspondente. Equipamentos que englobam esses dois elementos podem ser câmeras digitais e scanners (CARVALHO, 2003). A Figura 3 ilustra o processo de aquisição e processamento de imagens digitais.

Figura 3 - Seqüência de passos em sistemas de processamento digital de imagens (LAGEMANN, 2007)

Em suma, a Figura 3 demonstra os passos realizados para a aquisição e processamento de imagens. Primeiramente, o objeto é observado e digitalizado. Após isso, os dados digitalizados são armazenados para, só assim, poderem ser processados. Para este trabalho, a seqüência de passos definidos na Figura 3 são mais bem entendidos após uma leitura da seção 2.1.1.1, que apresenta o processo de aquisição de imagens médicas do tipo tomografia computadorizada. Após o armazenamento da imagem, o processamento pode ser iniciado, como ilustrado na própria figura. O processamento será definido teoricamente na seção 2.1.3, filtragem de imagens, e na prática, na seção 3, metodologia.

(11)

2.1.1.1 Tomografia Computadorizada

A tomografia computadorizada é um exame de raios-X auxiliado por Computador (RÚBIO, 2003). Seu princípio básico é um tubo de raios-x girando em volta do eixo do paciente ao longo da sua altura, dos pés a cabeça (OLIVEIRA, 2007). Os raios-X atravessam o corpo do paciente e são captados do lado inverso a emissão dos raios por dispositivos detectores. Os detectores captam o raio-X bem como o seu nível de atenuação ao passar pelo corpo. É a densidade das regiões atingidas que define o quanto os raios serão atenuados. O resultado da detecção compreende um conjunto de fatias, correspondendo a cortes transversais do corpo.

Cada corte é associado a uma matriz bidimensional normalmente de 512x512 pixels. Quando o eixo Z é considerado, a região passa a ser compreendida como um voxel, que possui como intensidade o nível de atenuação mensurado pelos detectores. Um voxel nada mais é, portanto, que uma unidade de imagem 3D, assim como um pixel é uma unidade de imagem 2D. A Figura 4 ilustra um diagrama de um sistema Tomografia Computadorizada (CT), envolvendo a detecção e a formação de fatias do objeto de estudo.

Figura 4 - Processo de aquisição de tomografia de um crânio (Fonte: FREUDENRICH, 2010)

(12)

O grau de atenuação dos raios-X em CT são medidos em Hounsfield (Hounsfield Units -HU), em homenagem ao inventor da tomografia computadorizada axial Godfrey Newbold Hounsfield, em 1972 (RÚBIO, 2003). A base da unidade de Hounsfield, ou HU, é a água, que tem seu valor associado a zero HU. Porções com densidades menores que a da água recebem valorações negativas. Do contrário, para densidades maiores, são associados valores positivos. Dessa forma, algumas deduções podem ser realizadas, com valorações médias para órgãos humanos. O rim humano, por exemplo, possui valorações HU que variam em média de 27 a 15 HU. Porções na localização do rim com coeficientes de absorção superiores a esse intervalo podem, provavelmente, ser um cisto, uma calcificação. A Tabela 1 apresenta a intensidade de absorção de alguns componentes anatômicos.

Tabela 1

Coeficiente de absorção de tecidos no exame de TC em HU

(Fonte: OLIVEIRA, 2007)

2.1.2 Ruídos

Ruídos podem ser definidos, em imagens digitais, como a presença de valores discretos nas imagens que não correspondem ao objeto real, comprometendo, em muitos casos, a clareza na sua visualização. Segundo Seara (2008), qualquer aquisição de imagens é suscetível a ruídos, não existindo, portanto, uma situação sem ruídos. Além disso, por terem uma origem aleatória, não há como prever sua existência, nem tão pouco mensurá-la previamente. O ruído é geralmente causado pelos seguintes fatores (QUIORIN, 2004):

(13)

• Variação de brilho da imagem de saída do intensificador de imagens; • Variação dos tons de cinza da imagem registrada pela câmera;

Filho e Neto (1999) destacam quatro tipos comuns de ruídos. O primeiro é o ruído

distribuído uniformemente. Assim, para dois valores a e b em níveis de cinza, entre 0 e 255,

a probabilidade de ocorrer um ruído com o tom de cinza dentro da faixa de a a b é de 1/(b-a). Como exemplo, se b = 150 e a = 50, o ruído estará entre 50 e 150, e cada valor nesse intervalo tem a probabilidade de 1% de ocorrer.

Um segundo tipo de ruído é o Gaussiano. Esse tipo ocorre principalmente devido ao ruído eletrônico presente em câmeras. O ruído gaussiano diminui sua probabilidade de ocorrer à medida que seu nível de cinza se distancia do nível de cinza central do histograma. Seu comportamento é definido no fato de que a soma de variáveis aleatória com a mesma distribuição de probabilidade tender ao formato gaussiano. Por exemplo, o ato de jogar um dado para cima gera uma frequência retangular, de 1/6 para cada face. Todavia, a probabilidade da soma dessas variáveis tende a um formato gaussiano.

O terceiro tipo de ruído é o de distribuição exponencial negativa e ocorre porque as superfícies iluminadas por laser são geralmente irregulares comparadas com o comprimento de onda do laser (FILHO; NETO, 1999). Sua conseqüência é existir maior probabilidade de ruídos próximos a zero, decaindo rapidamente para valores distantes de zero.

Por último, existem ainda os ruídos do tipo Salt and Pepper Noise (Sal e Pimenta). Ruídos do tipo sal e pimenta ocorrem a partir de erros na transmissão de dados, e se caracterizam por possuírem uma diferença grande em nível de cinza em relação aos seus vizinhos. Esse ruído contém dois níveis de cinza, com probabilidade de ocorrência igual a “p” cada um. Sua nomenclatura se dá pela aparência do ruído, onde os pixels ruidosos brancos são chamados sal, enquanto os pixels de ruído preto são chamados pimenta (QUOIRIN, 2004). Os quatro tipos de ruídos são apresentados na Figura 5.

(14)

Figura 5 - Histogramas dos principais tipos de ruído: (a) Ruído Uniforme; (b) Ruído Gaussiano; (c) Ruído Exponencial Negativo; (d) Ruído Sal e Pimenta (FILHO; NETO, 1999)

2.1.3 Filtragem de imagens

O processo de filtragem de imagens corresponde a, principalmente, detectar propriedades pertinentes na imagem, no intuito de destacá-las. Assim, filtragens poderão detectar bordas da imagem ou mesmo reduzir ruídos oriundos do processo de captura. Segundo Filho e Neto (1999), o principal objetivo do realce da imagem é processar certa imagem de modo que a resultante seja mais adequada que a original para uma aplicação específica. Dessa forma, a adequação do resultado do processamento se mostra subjetiva, além de depender do conhecimento prévio do observador a respeito das imagens analisadas. Além disso, vale ressaltar que não existe técnica plenamente eficaz, e que o seu desempenho pode variar bastante a depender do tipo de imagem processada. Como exemplo, técnicas que podem ser bastante eficazes no processamento de imagens tomográficas podem apresentar desempenho insatisfatório sobre imagens geográficas.

A filtragem de imagens é normalmente dividida em duas partes: Filtros no Domínio

do Espaço e Filtros no Domínio da Frequência (FILHO;NETO,1999). A primeira técnica

opera diretamente sobre a imagem a ser processada, utilizando convolução de seus valores discretos na utilização de mascaras. A convolução pode ser conceituada como um operador que, a partir de duas funções, produz uma terceira, num conceito de média móvel e aplicável

(15)

no estudo de sistemas lineares invariantes no tempo. A segunda técnica estende de um assunto conhecido por Transformada de Fourier, que não foi aplicada nesse trabalho. Todavia, a técnica, muito sumariamente, opera no domínio da freqüência sobre a forma de histogramas. Por meio da transformada, é possível definir as contribuições de cada freqüência para imagem como um todo. Dessa forma, operações de realce podem ser definidas de acordo como as contribuições de cada freqüência são manipuladas.

Em relação aos filtros, duas classificações são pertinentes: Filtros de Suavização e

Filtros de Aguçamento (LAGEMANN, 2007). A primeira, também chamada de filtro

passa-baixa, criam um efeito desfocado na imagem, atenuando o contraste com os pixels vizinhos. Esse filtro tem aplicação voltada principalmente à etapa de pré-processamento, na retirada de ruídos ou na exclusão de detalhes (GONZALEZ; WOODS, 2002). A segunda classificação tem como objetivo realçar detalhes possivelmente borrados na imagem, salientando os detalhes finos.

O conceito de filtros lineares pode ser exposto para melhor explicação da utilização de máscaras na suavização de imagens no domínio espacial. Segundo Filho e Neto (1999, p. 85), “os filtros lineares se baseiam no conceito de que a função de transferência de um sistema linear (H(u,v)) e sua função de resposta a impulso unitário (h(x,y)) estão relacionadas entre si por meio da transformada de Fourier”, como ilustra a Figura 6.

Figura 6 – Domínio espacial: a saída do sistema é obtida através da convolução de sua entrada com sua função de resposta a impulso unitário h(x,y) (FILHO; NETO, 1999)

A classificação como filtros passa-baixa vale quando ele atenua ou elimina as altas freqüências no domínio da transformada de Fourier. De certa forma, freqüências altas estão associadas a bordas e contornos das figuras. Assim, filtros desse tipo acabam dando um efeito borrado à imagem, suavizando-a. Os filtros passa- alta, pelo contrário, atenuam ou eliminam baixas freqüências, o que acaba aumentando o contraste e prevalecendo os contornos e bordas. Um terceiro filtro, chamado passa–faixa, mantém duas freqüências de corte, uma superior e outra inferior, sendo capaz de atenuar freqüências superiores a sua freqüência de

(16)

corte superior ou inferiores a sua freqüência de corte inferior. A Figura 7 apresenta esses três filtros lineares bem como os três filtros espaciais correspondentes:

Figura 7 – (Acima) Resposta em freqüência dos principais tipos de filtros. (Abaixo) Filtros correspondentes no domínio espacial. (FILHO; NETO, 1999)

Como visto na Figura 7, para implementação do filtro passa-baixa, o filtro espacial apresenta coeficientes positivos. Uma alternativa simples de implementar um filtro como esse é admitir uma matriz de tamanho 3 por 3, ou seja, 3 linhas por 3 colunas, aqui chamada de máscara 3x3, com todos os coeficientes iguais a 1, e dividir o resultado por um fator de normalização, 9, calculado pelo próprio tamanho da máscara. Os valores discretos da máscara podem ser ponderados, assim como o tamanho da máscara e, por conseqüência, o fator de normalização. Todavia, a adoção de valores fortemente discrepantes acaba reduzindo a qualidade da imagem, uma vez que pequenos detalhes tendem a desaparecer junto com os ruídos. Esse processo como um todo é concebido como filtro por Média. A máscara descrita é vista na Figura 8.

(17)

Uma das principais limitações do filtro da Média, em situações onde o objetivo é remoção de ruídos em imagens, está na sua incapacidade de preservar bordas e detalhes finos da imagem. Para contorná-la, uma técnica alternativa é o filtro da Mediana (FILHO; NETO, 1999, p. 90). O diferencial desse filtro é que, enquanto no filtro da Média, o valor discreto era substituído por um valor novo, calculado pela média de sua vizinhança, no filtro por Mediana, o valor novo é o que ocupa posição mediana quando seus vizinhos estão ordenados. Quando o número de vizinhos considerados é par, a mediana é a média dos dois valores centrais. Quando ímpar, a mediana é o próprio valor central.

Um problema relacionado ao filtro por Mediana está ligado a ordenação da vizinhança dos pixels, o que constitui uma etapa de tempo de processamento bastante custosa. Uma alternativa para implementação do filtro por Mediana introduz o termo pseudomediana, proposto por Pratt et al (1984). O estabelecimento do cálculo da pseudomediana é definido como na Figura 9.

Figura 9 – Cálculo da pseudomediana. (FILHO; NETO, 1999)

2.2 VISUALIZAÇÃO VOLUMÉTRICA E TÉCNICAS DE VISUALIZAÇÃO

De acordo com Mccormick (1987 apud PAIVA;GATTASS,1999, p. 6), “visualização volumétrica é um conjunto de técnicas para a interpretação de dados representados em computador e para a geração de imagens a partir de conjuntos de dados complexos e

(18)

multidimensionais”. Desta forma, o processo de visualização volumétrica compreende representar, num ambiente virtual, um conjunto de dados tridimensionais adquiridos pelos mais variados tipos de equipamentos, dentro das mais diversas ciências, permitindo sua exibição e exploração. A esse processo de visualização volumétrica realizado com o objetivo de obter uma melhor compreensão da estrutura contida nos dados volumétricos dá-se o nome de rendering (PAIVA; SEIXAS; GATTASS, 1999).

Os dados volumétricos estudados podem ser oriundos tanto de uma simulação, a partir de algum modelo matemático, quanto de uma aquisição, a partir de dados resultantes da conversão de objetos existentes na natureza. No primeiro caso, a simulação, acaba ocorrendo quando os fatores de aquisição comprometem uma possível aquisição de dados, como velocidade do objeto ou condições inóspitas de ambiente. Quando fatores como estes não acontecem, a segunda forma, aquisição, pode ser praticada.

Quando a aquisição é possível, ela pode ser obtida por meio de Ressonância Magnética (MRI), Tomografia Computadorizada, Ultrasonografia(US), Emissão de Pósitron (PET) e Emissão de Fóton (SPECT), ou de técnicas como varredura por laser (microscópicos confocais) e varredura por elétrons (microscópios eletrônicos) (PAIVA; SEIXAS; GATTASS, 1999). Essa variedade tecnológica na aquisição de imagens permite que técnicas de visualização volumétricas sejam utilizadas nas mais vastas áreas científicas que careçam de formas de analisar, visualizar e explorar internamente volumes de dados multidimensionais. Na área médica, por exemplo, com destaque às CT’s, estas técnicas auxiliam no acompanhamento de uma cirurgia assistida ou mesmo para auxiliar no diagnóstico médico.

As técnicas de visualização de volumes são classificadas em dois grupos: Surface Rendering (visualização através de superfícies) e Volume Rendering (visualização direta de volume) (KAUFMAN, 1997), vistas nas Figuras 10 e 11, respectivamente. A primeira envolve a extração e a representação de uma camada superficial com propriedades similares no volume, utilizando, para visualizá-la, técnicas convencionais de computação gráfica. A segunda, entretanto, mantém a visualização através de voxels tridimensionais (3D), projetados diretamente em pixels bidirecionais (2D) e armazenados como uma imagem.

A primeira técnica tem grande destaque na velocidade para a geração e exibição da imagem final e no pouco espaço de armazenamento requerido (MANSSOUR; FREITAS, 2002). Todavia, é perfeitamente aplicável quando existem superfícies bem definidas nos dados, o que não é o caso de imagens médicas, por serem compostas por diversas microestruturas. Para imagens médicas, a técnica de visualização direta do volume acaba

(19)

sendo a mais eficaz, uma vez que é possível o processamento individual de todos os voxels, possibilitando a visualização do interior dos objetos.

Figura 10 – Volume gerado pela técnica Surface Rendering. (OLIVEIRA, 2007)

Figura 11 – Volume gerado pela técnica Volume Rendering . (OLIVEIRA, 2007)

O processo de rendering pode ser definido em quatro etapas, como visto na Figura 12. A primeira etapa é a formação do volume. Este nível compreende a aquisição ou simulação dos dados bem como possível pré-processamento para retirar ruídos. Após isso, o volume passa par a etapa de classificação, o que normalmente acontece com auxílio do usuário, no processo de isolar áreas, definindo as estruturas existentes do volume (PAIVA; SEIXAS; GATTASS, 1999). A interação com o usuário e a identificação de estruturas internas é realizada principalmente com a manipulação de funções de transferência, abordadas na seção 2.2.2, quando a técnica é a de visualização direta, ou na definição de limites (threshold) do volume, na técnica de extração de superfícies.

(20)

Figura 12 –Processo de visualização volumétrica (Fonte: próprio autor)

A próxima etapa, iluminação, é responsável pela aparência do objeto (PAIVA; SEIXAS; GATTASS, 1999). Essencialmente, esta etapa presume como deve ser a interação dos tipos de luzes e de fontes, e suas posições, em relação ao objeto. Tal etapa pode mudar os valores especificados pelas funções de transferência, da etapa de classificação, visando aproximar ainda mais o objeto a um realismo 3D.

A última etapa compreende a projeção, ou, simplesmente, a visualização do conjunto de dados escalares no plano da imagem. Para a técnica de visualização direta, algoritmos de construção de volume se baseiam no princípio onde os voxels são projetados a partir de raios lançados de cada pixel da tela ou do volume, sendo a cor final de cada pixel definida pela combinação de opacidade e cor de cada voxel que fora atingido pelo raio (OLIVEIRA, 2007).

2.2.1 Visualização através de superfícies

A técnica Surface rendering (visualização através de superfícies) tem o papel de ajustar um modelo geométrico aos dados, a partir de parâmetros fornecidos pelo usuário (ELER, 2006). A construção do volume utilizando esse modelo recai em técnicas convencionais de computação gráfica, na composição de malha de polígonos a partir da

(21)

identificação da estrutura de interesse, fornecida, por exemplo, pela interação com usuário fornecendo limites para o volume, além de outros parâmetros que estabelecem o tipo e a direção de projeção e os parâmetros de iluminação (MANSSOUR; FREITAS, 2002).

Algoritmos pertencentes a esta classe possuem como grande vantagem a velocidade para a geração da imagem final e o pouco espaço requerido em memória (OLIVEIRA, 2007). Todavia, mantêm como desvantagens situações onde, no processo de ajuste, podem ser inseridos dados não presentes nos valores originais, bem como pode não existir clareza em estruturas mais internas (ELER, 2006). A técnica não é, portanto, aconselhada a ser utilizada em volumes sem forma definida ou que possui diversas microestruturas que precisam ser detalhadas, como volumes médicos, por exemplo.

2.2.2 Visualização direta de volume

A técnica de visualização direta de volume reúne mecanismos para gerar imagem diretamente sobre os dados volumétricos, sem precisar criar uma representação intermediária. Em outras palavras, a representação nessa categoria permite a visualização de voxels 3D diretamente em pixels 2D, como uma imagem. Algoritmos dessa categoria podem ser subdivididos em duas categorias principais, sendo estas: espaço dos objetos e espaço das

imagens (PAIVA; SEIXAS; GATTASS, 1999). Na primeira, o mapeamento é feito de forma

direta sobre o volume, obedecendo a uma ordem determinada de visita aos voxels. Cada voxel contribui com sua cor e opacidade para formação da imagem. O processo se finda quando todos os voxels são processados.

Na segunda categoria, o processo é inverso. O raio parte do ponto de vista do observador, poupando recursos computacionais, na tentativa de prever qual a distância que os voxels estão da fonte observadora. O raio intercepta o volume e, para cada voxel encontrado, sua cor e opacidade vão sendo acumuladas, construindo o valor final do pixel. As duas categorias são representadas na Figura 13.

Confere às funções de transferência o papel de dar as propriedades de cor e opacidade aos voxels. Variando tais funções, pode-se obscurecer ou realçar determinadas áreas do volume. Para dados médicos, por exemplo, regiões ósseas e calcificações, em geral, podem se aproximar do branco, enquanto músculos e gorduras, à tonalidades mais escuras. Todavia,

(22)

encontrar boas funções de transferência pode ser bastante custoso, muitas vezes recaindo a técnicas empíricas de tentativa e erro.

Figura 13 – (a) Espaço da imagem e (b) Espaço do objeto (OLIVEIRA, 2007) 2.2.2.1 O algoritmo de Ray Casting

O algoritmo Ray Casting é um dos mais utilizados para a apresentação de dados médicos (RÚBIO, 2003). Este algoritmo pertence a técnica de visualização direta de volume, e é utilizado no projeto apresentado nesse relatório, na etapa final. Essa escolha se baseia nas características apresentadas que permitem visualização de detalhes internos do volume. No caso específico, volumes médicos tendem a apresentar diversas microestruturas que, se fossem utilizadas técnicas da primeira categoria, certamente poderiam ser inseridos artefatos que não estão presentes nos dados (OLIVEIRA,2007). Em outras palavras, pode não existir clareza na visualização das microestruturas, o que pode ocultar informações importantes, principalmente quando se trata de volumes médicos e carecem de um diagnóstico mais preciso.

O algoritmo de Ray Casting, ainda que consagrado, tem um desempenho insatisfatório, devido a quantidade de cálculos que são necessários para determinar a cor do

pixel (RÚBIO, 2003). A paralelização é uma das formas de atenuar tal problema, que é de alto

custo computacional, e pode ser realizada facilmente, uma vez que os valores dos pixels podem ser determinados por meio do lançamento de raios independentes entre si (PAIVA; SEIXAS; GATTASS, 1999).

Resumidamente, o funcionamento do Ray Casting consiste na varredura dos pixels da janela de visualização e no lançamento de raios, a partir desses pixels, na direção do volume

(23)

de dados (object-order) (MANSSOUR; FREITAS, 2002). A formação da imagem bidimensional depende, portanto, do processamento realizado por esses raios que incidem sobre o volume 3D. A Figura 14 ilustra o esquema genérico do algoritmo de Ray Casting.

Figura 14 - Esquema genérico do algoritmo de Ray Casting (front-to-back) (MANSSOUR; FREITAS, 2002).

No plano de projeção (u,v), os pixels são mapeados mediante o processamento das intensidades amostradas por raios R na direção de DOP. As amostras dos Raios R mantém um intervalo normalmente constante. Para cada amostra, é calculada a sua cor e sua opacidade. Sendo a imagem bidimensional formada para visualização dada por I, tem-se que:

I(u) = g(R), (1)

onde g( R ) determina a cor do pixel (MANSSOUR; FREITAS, 2002). Por sua vez, g( R ) é definido como (2):

g( R ) = ∑ f(x), (2)

sendo f(x) uma função que define a importância quantitativa da intensidade de cada amostra para a intensidade final no pixel.

(24)

2.3 – HARDWARE ESPECÍFICO

Uma das maiores dificuldades no desenvolvimento e utilização de algoritmos que

utilizem a técnica de visualização direta de volume é a grande quantidade de dados envolvida no processo de visualização, dada certa limitação de armazenamento e processamento dos computadores (MANSSOUR; FREITAS, 2002).

Uma das tentativas para resolver esse problema é a otimização dos algoritmos. Em uma dessas otimizações, o algoritmo de Shear-Warp (LACROUTE,1995), são realizadas transformações matriciais no volume a fim de que o sentido dos raios de amostragem seja a mesma das linhas do volume. Todavia, em muitas dessas alternativas, incluindo o algoritmo

Shear-Warp, se faz necessário a utilização de estruturas de dados complexas, aumentando o

tempo de pré-processamento. No geral, três estratégias podem ser utilizadas: 1. Computadores com arquitetura paralela

2. Hardware específico 3. Placas aceleradoras gráficas.

A primeira alternativa pode ser contemplada na construção de programas distribuídos, seja numa máquina com um processador de vários núcleos ou num conjunto de computadores num ambiente de computação distribuída sob o paradigma de troca de mensagens ou de memória compartilhada.

Na segunda alternativa, utilização de hardware dedicado, Kaufman (1990) faz um levantamento das arquiteturas existentes para visualização volumétrica. Dentro da pesquisa, as tecnologias descobertas foram, principalmente, o EM-CUBE e o VolumePro (MANSSOUR, 2002). O EM-Cube é um exemplo de arquitetura VLSI (Very Large Scale Integration, integração em escala muito grande), onde oito estágios de

pipelines implementam o algoritmo de Ray Casting com projeção paralela para visualização

de volumes com baixo custo e alta qualidade (OSBORNE et al.1997). Já o VolumePro é um chip que permite o rendering de um volume a partir dos parâmetros de visualização, passados em tempo real. A técnica implementa o algoritmo de Ray Casting com processamento paralelo e interpolação trilinear (PFISTER et al. 1997).

Na terceira alternativa, a paralelização pode ser possível utilizando a tecnologia

Graphics Processing Unit (GPU), ou Unidade de Processamento Gráfico, disponível em

algumas placas aceleradoras. Neste caso, placas desse tipo mantêm funções de iluminação e transformações sobre os vértices do volume. Aliado a isso, a tecnologia OpenCL, que será

(25)

abordada na seção 2.5, permite que os cálculos de funções possam ser paralelizadas dentre os diversos GPU’s disponíveis na placa aceleradora. Assim, o processo de rendering é feito utilizando o mapeamento de textura 3D da placa de aceleradora, usando recursos como OpenGL, que se trata de uma API para desenvolvimento de aplicativos gráficos, ambientes 3D, dentre outros. Todavia, a parte crucial do processo ou, em outras palavras, que requer maior processamento, é alcançada paralelizando parte do código e destinando tais partes para que os GPU’s a realizem.

2.4 – COMPUTAÇÃO PARALELA E A TAXONOMIA DE FLYNN

A idéia de software mais rápido sempre se deu à medida que crescia o uso de CPU’s com altas velocidades de clock, velocidades estas que aumentavam consideravelmente com o passar dos anos. Todavia, por volta de 2004, quando os processadores alcançaram uma média dos 4GHz, o aumento do consumo de energia e da dissipação de calor formou o que se conhece por “Power Wall”, ou “Parede de Energia” (TSUCHIYAMA et al., 2010).

Dessa forma, os vendedores foram forçados a desistir de seus esforços de aumentar a velocidade de clock, adotando, então, um método de incremento no número de núcleos (cores) dentro do processador. Nesse caso, para poder utilizar toda eficiência disponível, o

software deve ser desenvolvido em paralelo. Hoje em dia, CPU’s dual-core são comuns em desktops e notebooks. Isto evidencia que processamento paralelo não é útil apenas para

realizar computações avançadas, mas também para aplicações diversas.

O termo Computação Paralela pode ser definido como a execução simultânea de uma mesma tarefa em múltiplos processadores e em uma determinada ordem a qual permita obter o resultado em um menor tempo possível (CAETANO, 2005). Muitas arquiteturas diferentes de hardware existem hoje para realizar uma única tarefa utilizando múltiplos processadores. Alguns deles são (TSUCHIYAMA et al., 2010):

• Grid Computing – Uma combinação de recursos computacionais de múltiplos domínios aplicados a uma mesma tarefa

• MPP (Massively Parallel Processor) – Arquitetura de supercomputadores • Cluster – Uma rede de computadores de propósito geral

(26)

• SMP (Symmetric Multiprocessing) – Processadores idênticos (em força de 2) conectados de forma a trabalharem como uma unidade.

• Multi-core processor – Um único chip com numerosos cores.

A taxonomia de Flynn é uma classificação de arquitetura de computador proposta por Michael J. Flynn (FLYNN, 1972). Sua classificação se baseia na concorrência de instruções e dados. A classificação segue abaixo:

a) Single Instruction, Single Data (SISD)

Trata-se de uma seqüência de onde a instrução processa sobre apenas um stream de dados. Entende-se stream como um conjunto a ser processado. PC’s anteriores ao ano 2004 são desse tipo.

b) Single Instruction, Multiple Data (SIMD)

Nesse tipo, uma instrução é realizada sobre vários dados. Um vetor processador, originado nos supercomputadores, é um exemplo dessa categoria. São adequados para tratar processos onde os dados não mantêm uma relação direta entre si, podendo ser processados paralelamente. Assim, uma mesma instrução é realizada sobre vários conjuntos de dados, ao mesmo tempo.

c) Multiple Instruction, Single Data (MISD)

Aqui, múltiplas instruções são executadas sobre o mesmo conjunto de dados. Não existem muitas aplicações nessa categoria, com exceção de sistemas tolerantes a falta, onde a redundância de processamento se faz necessária.

d) Multiple Instruction, Multiple Data (MIMD)

Consiste em múltiplas instruções sobre múltiplos dados. Os processadores mantêm um comportamento assíncrono, podendo a qualquer momento operar instruções diferentes sobre conjuntos de dados distintos. Sobre essa classificação, dois tipos de memória são possíveis: Memória Compartilhada e Memória Distribuída. Na primeira, a memória é vista como global, sendo uma forma melhor compreendida pelo programador, uma vez que a coerência da memória passa a ser tarefa do SO, e não escrita no programa. Na segunda, cada processador não tem um conhecimento direto sobre memória do outro processador, devendo ocorrer então troca de mensagens entre eles.

A implementação de um código paralelo carece das seguintes etapas:

1 – Análise da dependência dentro da estrutura de dados ou dos processos, no intuito de descobrir quais seções podem ser executadas em paralelo.

(27)

3– Reescrever o código utilizando frameworks como Message Passing Interface(MPI),

OpenMP ou OpenCL.

O tempo de processamento final tende a diminuir, obviamente, quando o processamento é paralelo, em relação ao serial. Por exemplo, para apenas um processador, considerando Ts como o tempo de processamento que não pode ser paralelizado e Tp, do que pode ser paralelizado, tem-se que:

T(1) = Ts + Tp (3)

Utilizando N processadores, o tempo é:

T(N) = Ts + Tp/N (4)

Outra abordagem relaciona o tipo de paralelismo com a seguinte classificação: Paralelismo por dado e paralelismo por tarefa. Na primeira, o paralelismo é feito sobre os dados, como o próprio nome diz, atribuindo a mesma instrução sobre conjuntos diferentes de dados. Trata-se de uma técnica mais eficiente quando os dados mantêm uma dependência mínima, ou zero, entre eles. Quando isso não é possível, a segunda classificação, paralelismo por tarefa, pode ser mais aplicável. Aqui, cada tarefa realiza instruções diferentes, paralelamente. Para um exemplo de soma de dois vetores, a abordagem de paralelização por dados é vista na Figura 15. A Figura 16 ilustra um caso genérico de paralelização por tarefa.

(28)

Figura 16 – Paralelização por tarefa (Fonte: próprio autor)

Na Figura 15, todos os processos são iguais, porém atuam sobre dados diferentes. Isso é evidenciado na Figura 15 pelo índice i associado a cada processo. Para o exemplo da Figura 16, as tarefas podem ser diferentes, atuando sobre dados diferentes, ou não.

2.5 – O FRAMEWORK OPENCL

Essa seção aborda conceitos referentes a API OpenCL. Na subseção 2.5.1 a API é definida como uma arquitetura padrão para computação paralela sobre sistemas heterogêneos. A subseção 2.5.2 detalha a hierarquia de modelos definida pela especificação da linguagem

OpenCL.

2.5.1– A API OpenCL

A diferença fundamental entre processadores (CPU) e os chipsets de vídeo (GPU) é que as CPU’s são destinadas principalmente para cálculos seqüenciais, servindo para as mais diversas aplicações, enquanto que GPU’S estão orientadas a cálculos paralelos, em processamentos 3D (MORIMOTO, 2009). A distinção entre CPU’s e GPU’s se minimiza

(29)

com a crescente capacidade que os GPU’s vêm adquirindo de executarem código seqüencial, de forma semelhante a processadores convencionais. Isso permitiu a existência atual de programas chamados shaders, que possibilitam um maior controle sobre o hardware gráfico por parte dos desenvolvedores (GUSMÃO,2010). Programas desse tipo acabam possibilitando que os desenvolvedores implementem avanços na iluminação e mapeamento de sombra mais reais, saindo assim da rotina de pipelines das API’s gráficas convencionais como OpenGL e Direct3D, que não utilizam uma característica de execução paralela.

A abordagem de paralelizar tarefas, principalmente gráficas, não visa aumentar o número de núcleos do processador ou mesmo substituí-lo por uma placa de vídeo. Mais que isso, pretende-se expandir a disponibilidade e escalabilidade no processamento de desktops, em aplicações específicas que, naturalmente, requerem intenso processamento, e que seu código pode ser paralelizado, num grau de dificuldade considerável.

OpenCL pode ser conceituada como uma nova linguagem de programação de GPU’s

proposta pela Apple em 2008, desenvolvida pelo KHRONOS GROUP em parceria com empresas como Intel, AMD, NVIDIA e IBM (GUSMÃO, 2010). A proposta existe no intuito de fundamentar uma arquitetura padrão para computação sobre sistemas heterogêneos numa idéia de portabilidade. Isso quer dizer que a linguagem deve ser executada de forma igual entre distintos hardwares, sem dependência direta. A Tabela 2 ilustra uma comparação de códigos desenvolvidos de forma convencional e utilizando OpenCL.

Tabela 2

Comparação de código normal e com OpenCL

Tópico Código normal OpenCL

Trabalhadores (processos) executando

código (threads) Usualmente um Tipicamente milhares

Funções de cálculos com vetores acelerados por

hardware? Não

Sim, em GPUs e aceleradores Possível usar todos os devices de

processamento disponíveis para processamento

simultaneamente? Não Sim

Multithreading precisa de locks explícitos de

objetos? Sim Não

Necessário setar manualmente o número de

processos? Não Sim

Fácil de usar algoritmos existentes? Sim Não

É necessário desenvolvimento especial para

fazer o código ser executado em paralelo? Não Sim

Disponibilidade e suporte amplos? Sim Não

(30)

Tal portabilidade não é vista em outras API’s que utilizam a tecnologia de GPU’s. CUDA, por exemplo, é a arquitetura de computação paralela da empresa NVidia, tal como o Brook+ é uma extensão da empresa AMD. Tanto CUDA como Brook+ utilizam a linguagem de programação C e suas variações, mas perdem por não oferecerem disponibilidade a arquiteturas diferentes. OpenCL, portanto, se encaixa como uma API livre e genérica. Torna-se vantajosa por manter esTorna-se equilíbrio, porém, corre-Torna-se o risco de Torna-se resolver muitos dos problemas de paralelização utilizando funções mais comuns, por ser genérica, o que pode manter o desempenho longe do esperado (MORIMOTO, 2009).

O modelo geral de atribuição de tarefas para dispositivos pode ser visto na Figura 17. Um host (um dispositivo central) pode enviar informações e comandos de execução para dispositivos, e pode ler dados dos mesmos (ANDRADE, 2010). O host executa código convencional, utilizando a linguagem de programação de própria escolha. Os devices (dispositivos), executam código OpenCL específico, sejam eles CPU’s, placas aceleradoras ou GPU’s (ANDRADE, 2010).

Figura 17 – Esquema de atribuição OpenCL (ANDRADE, 2010)

2.5.2– Arquitetura OpenCL

A especificação da linguagem OpenCL a define numa hierarquia de modelos (KHRONOS OPENCL WORKING GROUP, 2010).

(31)

- Modelo de Plataforma - Modelo de Execução - Modelo de Memória e - Modelo de Programação

No primeiro, o modelo consiste em um host conectado a um ou mais dispositivos

OpenCL. Cada dispositivo possui uma ou mais unidades computacionais que por sua vez

possuem um ou mais elementos de processamento. O processamento pode ser feito como um fluxo único no modelo SISD proposto pela taxonomia de Flynn, ou no modelo SIMD, da mesma classificação. Nesse último, cada elemento de processamento possui seu próprio contador de programa. A Figura 18 ilustra o modelo de plataforma, na hierarquia entre dispositivo (Compute Device), unidade computacional (Compute Unit) e elemento de processamento ( Processing Element), bem como na comunicação do dispositivo com o host.

Figura 18 – Modelo de Plataforma (Khronos OpenCL Working Group, 2010)

No modelo de execução, um programa OpenCL executa em duas partes: kernels que executam em um ou mais dispositivos OpenCL , e um programa host que executa, obviamente, no host. O programa, host define o contexto para o programa kernel e os gerenciadores de sua execução. Entende-se por contexto o ambiente onde o kernel possui domínio de execução e onde é definida a sincronia e a gerencia de memória. O contexto envolve um conjunto de dispositivos, o acesso a memória para esses dispositivos e mantém a ordem de solicitação, dita como Command-queue, em relação ao agendamento de execução do(s) kernel(s) ou operações sobre objetos de memória.

(32)

Quando ocorre uma execução de um kernel, promovida pelo host, tem-se uma instancia que é chamada work-item, passando a ser identificado como um ponto no espaço de endereço, recebendo uma identificação global. Work-items são organizados em Work-groups, no intuito de prover maior granularidade ao código sob a forma de melhor atribuição de tarefas. Assim, work-items podem ser referenciados pelo ID global, ou pela combinação do ID local, referente ao grupo, com o ID do work-group.

É de responsabilidade do host definir o contexto para execução dos kernels. Tal contexto inclui os seguintes recursos:

1. Devices: A coleção de dispositivos OpenCL a serem usados pelo host 2. Kernels: As funções OpenCL que executam nos dispositivos OpenCL.

3. Program Objects: O programa fonte e executável que implementam os kernels.

4. Memory Objects: Um conjunto de objetos de memória visíveis pelo host e pelos dispositivos OpenCL. Objetos de memória contém valores que podem ser operados pelas instancias dos kernels.

O contexto é criado e manipulado pelo host utilizando funções da API OpenCL. O

host cria estruturas chamadas command-queues para coordenar a execução dos kernels nos

dispositivos. A execução pode ser em ordem, como numa fila, ou fora de ordem, a partir de uma sincronização explicita por parte do programador.

O terceiro modelo da hierarquia OpenCL, modelo de memória, work-itens tem acesso a 4 regiões de memória distintas. São elas.

1. Memoria Global – Esse tipo permite acesso de leitura e escrita para todos work-itens em todos work-groups.

2. Memória Constante – Mesmo que memória global, porém se mantém constante durante a execução do kernel.

3. Memória Local – Trata-se de uma região de memória de um work-group. Pode ser usada para alocar variáveis que são compartilhadas por todos work-itens do mesmo

work-group.

4. Memória Privada – É a região de memória de apenas um work-item, não sendo visível por outro work-item.

(33)

Figura 19– Arquitetura conceitual de memória, com elementos de processamento, (Khronos OpenCL Working Group, 2009)

Por fim, o quarto modelo define a plataforma de programação, de igual forma ao que foi definido na seção 2.4, nos tipos de paralelismo por dados e por tarefas.

(34)

3 METODOLOGIA

Essa seção é subdividida em três: Softwares Utilizados, Decisões de projeto e Implementação.

3.1 SOFTWARE e HARDWARE UTILIZADOS

A primeira etapa do processo compreendeu a instalação de drivers e do Ambiente de desenvolvimento (Integrated Development Environment – IDE) a ser utilizado. Quanto a instalação dos drivers, se dispunha de placa de vídeo GeForce NVidia modelo 8300GT, que possui 512 MB de memória e clock do GPU de 450 MHz. Essa placa possui 8 GPU’s, que foram utilizadas no paralelismo do algoritmo de eliminação de ruídos. Foi utilizado um computador com processador de 2.06 GHz de memória e 2GB de memória RAM. Os drivers e programas utilizados são vistos na Tabela 3.

Tabela 3 Softwares utilizados

Categoria Nome

Sistema Operacional Windows Seven Ultimate

Ambiente de Desenvolvimento Microsoft Visual Studio 2008

Drivers Drivers de Desenvolvimento v.260.61

Software diversos CUDA Toolkit

GPU Computing SDK Code Examples

(Fonte: Próprio autor)

Quanto ao IDE, foram feitas tentativas de uso dos ambientes Netbeans 6.7 e Eclipse Galileo, porém foram sem sucesso no SO Windows. Não foram feitos testes utilizando versões Linux. Posteriormente, pôde ser percebido que, ao menos pelas fontes consultadas, o Visual Studio é compatível com a tecnologia, na plataforma Windows, passando então a ser utilizado no projeto.

(35)

3.2 DECISÕES DE PROJETO

Para o desenvolvimento do projeto, algumas decisões se fizeram necessárias. A primeira refere-se a passagem de dados para os kernels. Assim, alguns dados foram passados como parâmetro, e outros foram transmitidos diretamente para memória do dispositivo. Valores como número de linhas, colunas e altura da imagem foram passados como parâmetro, ao passo que dados maiores como o volume inicial e final, representados por matrizes unidimensionais oriundas do arquivo de entrada em formato raw, foram passados diretamente para a memória do dispositivo.

Uma segunda decisão foi a de como a tarefa seria dividida entre os kernels. Inicialmente, a idéia foi a de que cada GPU da placa de vídeo processasse uma parte do volume. Nesse caso, utilizando 4 kernels, cada GPU processaria um quarto do volume. Todavia, alguns erros em tempo de execução ocorreram, o que leva a dedução de que o processamento dessa forma esgota o tempo limite, disparando um evento de tarefa concluída.

Optou-se então dividir o processamento em loops, da seguinte forma: Ao invés de processar todo o volume de uma vez, processa-se etapas que compreendem a 4 camadas do volume, uma para cada GPU. Como exemplo, numa imagem hipotética que contenha 20 linhas x 20 colunas x 12 camadas, 3 loops serão necessários. Se fossem 11 camadas, o último loop processaria 3 apenas. Dessa forma, não aconteceram erros em tempo de execução como na idéia anterior.

Quanto aos algoritmos utilizados, atualmente estão sendo aplicados o cálculo da Média e da Mediana por se enquadrarem na categoria de algoritmos espaciais e de suavização, como discutido na seção 2.1.3 . A implementação do algoritmo da Média está sendo realizado considerando a vizinhança do pixel numa visão 3D, ou seja, considerando também a camada à frente e atrás da do pixel a ser processado, o que resulta em 26 pixels vizinhos como mostrado na Figura 20.

(36)

Figura 20 – Vizinhos de um pixel para o algoritmo da Média: a)Elementos de uma camada anterior. b) Elementos da camada que contém o pixel. c) Elementos de uma camada posterior. d) Vizinhos

do pixel de valor 84 considerando as 3 camadas. (Fonte: Próprio autor)

Quanto a implementação do algoritmo da Mediana, algumas limitações se mostraram necessárias. Uma vez decidido utilizar 26 pixels como vizinhos, a ordenação desses pixels gerou erros em tempo de execução, uma vez que cada GPU precisa fazer tal ordenamento. A limitação imposta foi a de reduzir esse número para 3 pixels, tornando o ordenamento mais simples, porém, infelizmente, diminuindo o potencial do algoritmo. Assim, no processamento do algoritmo da Mediana, estão sendo considerados os pixels da frente, o próprio, e o de trás. Isto é evidenciado na Figura 21.

Figura 21 – Vizinhos de um pixel utilizando o algoritmo da Mediana: a)Elementos de uma camada anterior. b) Elementos da camada que contém o pixel. c) Elementos de uma camada posterior. d) Vizinhos

do pixel de valor 84 considerando as 3 camadas. (Fonte: Próprio autor)

Os volumes de imagens utilizados passaram por uma etapa de inserção de ruídos do tipo Sal e Pimenta, utilizando a ferramenta ImageJ.

(37)

3.3 IMPLEMENTAÇÃO

O projeto desenvolvido processa imagens volumétricas obtidas através de tomografia computadorizada. Tais imagens se encontram na extensão raw. Esse formato garante que os dados se mantenham inalterados, sem nenhum tipo de compactação, garantindo a integridade das informações. Todavia, tal característica traz consigo duas desvantagens. A primeira refere-se ao tamanho da imagem, que tende a ser bem maior que imagens compactadas em JPEG ou GIF, por exemplo. A segunda característica refere-se a ausência de informações de cabeçalho do arquivo, que podia conter tamanho da imagem e seu formato. Assim, é necessário informar, no início do processamento, qual o tamanho da imagem a ser processada, em suas três dimensões.

A implementação se deu sobre duas visões. A primeira corresponde a programação do lado do host e a segunda, do lado do kernel. Essa divisão será descrita, respectivamente, na seção 3.3.1 e 3.3.2. Em suma, o projeto é apresentado na Figura 22.

(38)

A partir de um conjunto de dados obtidos pelo tomógrafo associado a um computador, que gera valores discretos relacionados aos graus de atenuação de Hounsfield, é gerado um arquivo de extensão raw que contém todos os valores discretos obtidos na aquisição. Todavia, a disposição desses dados em arquivos raw não obedecem nenhum critério de separação entre camadas, linhas e colunas do volume. Os dados são escritos linearmente no arquivo. Assim, com a inserção das dimensões da imagem através da execução do programa, o arquivo pode ser representado sob a forma de matrizes bidimensionais, onde cada uma dessas matrizes correspondem a camadas da tomografia computadorizada.

São inseridos ruídos do tipo Sal e Pimenta sobre as camadas e então, elas são processadas, de quatro em quatro, conforme descrição do paralelismo discutida na seção 3.2. Cada GPU processa uma camada em cada loop do processamento, gerando imagens com ruídos atenuados. O processo se finda quando todas as camadas são processadas e, desta forma, o volume final pode ser visualizado.

A seqüência de passos para implementação do projeto é apresentada na Figura 22.

Figura 22 - Fluxo da implementação (Fonte: Próprio autor)

Após serem inseridos os ruídos nas imagens, o programa host abre a imagem de entrada e gera a imagem de saída em diretório definido no programa. Após isso, o código paralelo, de extensão cl, que executa nos núcleos GPU, é carregado pelo programa host. O programa host espera então por entrada do usuário que correspondem às dimensões da imagem, para só assim alocar memória dinâmicamente no intuito de representar os arquivos

(39)

de entrada e saída. Feito isso, os argumentos do kernel são configurados, tais como tamanho da imagem, referência à memória utilizada para os pixels vizinhos, dentre outros. Neste ponto, o processamento se inicia, sendo passados para os núcleos GPU conjunto de 4 camadas, onde cada GPU processa uma camada por vez.

3.3.1– Implementação do lado do Host

Após carregamento da imagem a ser processada e conhecer informações sobre ela, é preciso iniciar processo de paralelização. Com a API OpenCL , um dos primeiros passos é conhecer qual plataforma e quais dispositivos estão disponíveis para execução da tarefa. Isso pode ser conseguido utilizando as instruções clGetPlatformIDs e clGetDeviceIDs apresentadas na Figura 23.

Figura 23 – Aquisição da plataforma utilizada e dos dispositivos disponíveis para paralelização. (Fonte: Próprio autor)

O argumentos platform_id e ret_num_platforms correspondem a listas de retorno que armazenam informações da plataforma e dos dispositivos, como identificação e quantidade. O argumento CL_DEVICE_TYPE_DEFAULT refere-se ao tipo de dispositivo a ser utilizado, no caso, GPU. O tipo default buscará no sistema qual o tipo de dispositivo OpenCL padrão.

O próximo passo é o de criar um ambiente de execução dos kernels, o que inclui o conjunto de dispositivos e a memória acessível para esses dispositivos. Esse ambiente é dito como contexto. Após isso, é possível construir um objeto, aqui chamado command_queue, que contém comandos que serão executados em um dispositivo específico, mantendo uma fila das tarefas a serem executadas. A criação desses objetos na linguagem OpenCL são vistos na Figura 24. O contexto criado é passado como argumento para criação do command_queue.

(40)

Figura 24 – Criação do contexto de execução e da fila de comandos. (Fonte: Próprio autor)

O próximo passo é o de alocação de memória para guardar a matriz de dados de entrada. Essa memória é do tipo cl_mem, definida na especificação da linguagem OpenCL. Após a memória ser alocada, ela é transferida para memória do dispositivo com o comando

clEnqueueWriteBuffer.A alocação e a transferência são vistas na Figura 25.

Figura 25 – Criação do buffer e transferência da memória para o dispositivo. (Fonte: Próprio autor)

O comando clCreateBuffer tem como argumentos o contexto e o tipo de memória a ser criada. Pelo exemplo, a memória foi definida como do tipo leitura e escrita. Outro argumento passado refere-se ao tamanho da imagem. No exemplo da Figura 25, o tamanho é definido pelos valores inteiros passados como entrada do usuário em relação à altura, largura e comprimento da imagem, aqui ditos como nalt, nlin e ncol, respectivamente.

O comando clEnqueueWriteBuffer recebe como argumento a memória criada, que aqui possui o nome MemoriaMatriz. Todavia, essa memória não possui os dados de entrada ainda. O arquivo de entrada é aberto com a função de abertura de arquivo convencional da linguagem C, que é a função fopen, e os dados são transferidos para um buffer de memória alocado dinamicamente, a depender do tamanho da imagem. São esses dados, aqui escrito como o argumento de nome buffer no comando clEnqueueWriteBuffer que serão processados no espaço de memória MemoriaMatriz.

(41)

Nesse ponto, é preciso criar o programa a ser executado pelo kernel. Isso é feito carregando o arquivo fonte que contém o código de extensão “.cl”. Esse código precisa ser aberto e deve-se gerar um objeto que funcione dentro do contexto criado. O arquivo que contém o código do kernel é aberto de igual forma com que foi realizada a abertura do arquivo de entrada, ou seja, utilizando a função fopen. O programa é criado utilizando o comando clCreateProgramWithSource e é compilado e linkado com o comando

clBuildProgram. Essa etapa é vista na Figura 26.

Figura 26 – Criação e compilação do programa kernel. (Fonte: Próprio autor)

O programa é criado com o comando clCreateProgramWithSource tendo como parâmetros o contexto de execução e o tamanho do programa, no caso, o argumento

source_size, passado por referência. O argumento source_str armazena o programa lido pelo

comando fopen.

O passo seguinte é o de criação de um objeto kernel. Um objeto kernel corresponde a uma função específica definida no código a ser executado pelo GPU. Assim, se torna necessário, na criação do objeto kernel, informar o nome da função a ser usada. O programa deve possuir uma função com o mesmo nome que é passado como parâmetro na criação do objeto. Uma vez que se tenha o objeto kernel criado, é necessário configurar seus parâmetros. O número de linhas, colunas e altura são recebidas do usuário, uma vez que o arquivo não contém informações de tamanho, como descrito na seção 3.3. Nesse trabalho, a dimensão das imagens foram conhecidos por fazerem parte do nome dos arquivos correspondentes às imagens utilizadas. A criação do objeto kernel e a configuração de seus argumentos podem ser vistos na Figura 27.

(42)

O kernel é criado com o comando clCreateKernel e seus parâmetros são configurados com o comando clSetKernelArg. No caso específico, a string “dataParallel” corresponde a uma função que existe no programa a ser executado pelo GPU, programa este representado por “program”, e assim, precisa necessariamente ter a mesma escrita. Os argumentos da função dataParallel são configurados informando a sua posição. É, então, tarefa do programador relacionar os números passados como argumentos na função clSetKernelArg com a posição de cada parâmetro do programa kernel. Como pode ser visto na Figura 27, são configurados valores inteiros, como largura e altura da imagem, bem como são referenciadas as memórias definidas no host, que relacionam a matriz inicial, final e o conjunto de pixels vizinhos.

Para iniciar o processamento, é preciso definir quantos work-groups e local-itens serão utilizados. Na pesquisa, foram utilizados 4 work-groups e 1 local-item. Assim, o objetivo foi de paralelizar a tarefa entre 4 núcleos GPU. Em outros momentos, foram realizados processamentos com 1 e 2 kernels, modificando o valor dos work-groups. A paralelização, conforme vista na seção 2.3, pode ser por tarefa ou por dado. Aqui foi utilizada a paralelização por tarefa, uma vez que os dados processados não possuem nenhuma dependência entre eles.

O comando OpenCL para o tipo de paralelismo por dado é o

clEnqueueNDRangeKernel. Caso fosse utilizada a paralelização por tarefa, o comando clEnqueueTask seria utilizado. O resultado da paralelização é transferido para o host através

do comando clEnqueueReadBuffer. A paralelização por dado e a transferência para o host do resulta são vistos na Figura 28.

Referências

Documentos relacionados

O primeiro carregamento analisado foi o de pressão interna, associada aos modos de falha por escoamento e vazamento, onde observou-se que os valores de

No sentido de reverter tal situação, a realização deste trabalho elaborado na disciplina de Prática enquanto Componente Curricular V (PeCC V), buscou proporcionar as

As pontas de contato retas e retificadas em paralelo ajustam o micrômetro mais rápida e precisamente do que as pontas de contato esféricas encontradas em micrômetros disponíveis

Os casos não previstos neste regulamento serão resolvidos em primeira instância pela coorde- nação do Prêmio Morena de Criação Publicitária e, em segunda instância, pelo

Portanto, mesmo percebendo a presença da música em diferentes situações no ambiente de educação infantil, percebe-se que as atividades relacionadas ao fazer musical ainda são

Foi apresentada, pelo Ademar, a documentação encaminhada pelo APL ao INMETRO, o qual argumentar sobre a PORTARIA Nº 398, DE 31 DE JULHO DE 2012 E SEU REGULAMENTO TÉCNICO

Neste trabalho avaliamos as respostas de duas espécies de aranhas errantes do gênero Ctenus às pistas químicas de presas e predadores e ao tipo de solo (arenoso ou

Este desafio nos exige uma nova postura frente às questões ambientais, significa tomar o meio ambiente como problema pedagógico, como práxis unificadora que favoreça