Abordagem paralela utilizando GPUs para contagem automática de ovos de Aedes Aegypti em imagens de ovitrampas Luis Fernando Veronese Trivelatto (ICV/Unioeste/PRPPG), Guilherme Galante(Orientador), e-mail: [email protected] Universidade Estadual do Oeste do Paraná/Centro de Ciências Exatas e da Tecnológicas/Cascavel, PR. Ciências Exatas e da Terra - Ciência da Computação Palavras-chave: CUDA, visão computacional, Aedes Aegypti. Resumo A computação paralela visa acelerar o tempo de execução de problemas que necessitem grande quantidade de processamento ao utilizar mais de um núcleo de processamento simultaneamente para resolver um problema. As GPUs são processadores maciçamente paralelos, especializadas em explorar paralelismo em problemas que apresentem alta quantidade de operações lógicas e aritméticas em relação a operações de controle de fluxo. Este trabalho apresenta um método para realizar contagem automática de ovos de Aedes Aegypti em imagens digitais de ovitrampas, observando que várias etapas do processamento necessário para tal apresentam características favoráveis para exploração de paralelismo na GPU. Utilizando a ferramenta CUDA, criou-se uma aplicação paralela para realizar tal contagem e comparou-se o tempo de execução da implementação na GPU com o tempo de execução da implementação sem explorar paralelismo. Introdução Uma das estratégias para controle da população do mosquito Aedes aegypti no Brasil é o emprego de ovitrampas, armadilhas especiais posicionadas estrategicamente para colher ovos do mosquito. Embora esta técnica seja barata e de fácil utilização, a contagem dos ovos presentes na ovitrampa geralmente é feita de modo manual por um técnico treinado, o que pode ser um processo lento e sujeito à falha humana, além de exigir profissionais especializados (Portela, 2009). Assim, métodos para realizar esta contagem de forma automática foram desenvolvidos. Estes métodos baseiam-se no processamento digital de uma imagem da ovitrampa para estimar o número de ovos presentes na mesma. Observa-se que a análise da imagem requer grande quantidade de processamento; além disso, diversas etapas desse processamento apresentam natureza paralela. Deste modo, pode-se usar computação paralela para diminuir o tempo de execução da análise da imagem, e, em particular, pode-se utilizar GPUs (unidades de processamento gráfico) para tal, uma vez que o problema em questão tem características que se encaixam no modelo de paralelismo apresentado pela GPU. O objetivo deste trabalho é desenvolver uma solução paralela utilizando GPUs, especificamente com a ferramenta CUDA, para realizar de forma automática a contagem de ovos de Aedes Aegypti em imagens de ovitrampas. Material e Métodos O método utilizado para a contagem automática de ovos em uma imagem pode ser dividido nas seguintes etapas (Portela, 2009): inicialmente, seleciona-se apenas a componente R da imagem, obtida no sistema de cores RGB. Então é feita a limiarização, que busca separar as regiões da imagem que representam ovos e o restante da imagem, que representa o fundo da ovitrampa. A etapa seguinte filtra as regiões encontradas na etapa anterior a fim de eliminar regiões pequenas demais para serem ovos, chamadas artefatos. Por fim, calcula-se a soma do tamanho das regiões restantes e obtêm-se uma estimativa do número de ovos na imagem a partir da razão entre este soma e o tamanho médio de um ovo (determinado experimentalmente). Estas etapas são descritas mais detalhadamente a seguir. Computacionalmente, uma imagem digital é representada como uma matriz bidimensional, onde cada ponto da matriz refere-se a um pixel. O sistema de cores RGB consiste na representação de cada cor como uma combinação das três cores primárias: vermelho, verde e azul. Assim, cada pixel armazena três valores inteiros referentes às componentes R, G e B. No que se refere às imagens de ovitrampas, observou-se que a componente R apresenta um alto contraste entre as regiões da imagem que representam ovos e o fundo da ovitrampa. Portanto, pode-se tomar estes valores para realizar a limiarização, que é uma técnica utilizada para separar as regiões de uma imagem em objeto e fundo. De modo geral, a limiarização gera uma imagem binária (isto é, uma imagem cuja representação matricial admite apenas valores 0 e 1) a partir de um limiar T, que separe os pixels da imagem em dois grupos. Encontrar um valor T que seja capaz de separar o objeto e o fundo em uma imagem é um problema complexo de processamento de imagens. Neste trabalho utilizou-se um limiar fixo de 200 para este processo. Isso gerou resultados adequados, pois a componente R apresenta alto contraste entre as regiões de ovos e o fundo. A figura 1 (esquerda) mostra a imagem original e (centro) mostra a imagem binária resultante da limiarização da componente R, onde pixels brancos representam o objeto (ovos) e pixels pretos representam o fundo ovitrampa. A etapa seguinte consiste na eliminação de artefatos. Observa-se que a imagem limiarizada apresenta considerável ruído; no entanto, o ruído raramente forma componentes conexos de pixels brancos de tamanho significativo, de modo que podemos selecionar os componentes conexos que representam ovos eliminando aqueles com tamanho pequeno. Observando o tamanho médio de um ovo em número de pixels nas imagens, determinou-se que áreas menores que 90 pixels seriam eliminadas. A figura 1 (direita) mostra a imagem após a etapa de eliminação de artefatos. Figura 1 - Imagem original (esquerda); imagem após limiarização (centro); imagem após eliminação de artefatos (direita). Por fim, conta-se o número de pixels brancos na imagem final e divide-se esse número por 80 para obter a estimativa do número de ovos na placa. A constante 80 foi escolhida levando em consideração não só o tamanho médio em pixels de um ovo nas imagens, mas também fatores de erro como a possibilidade de ovos se sobreporem, aparecerem inclinados, afetando sua área média, entre outros. Considerando que as imagens podem ter resolução com milhões de pixels, que pode haver um número grande de imagens para serem analisadas e que boa parte do procedimento descrito apresenta natureza paralela, é interessante utilizar processamento paralelo para diminuir o tempo de execução da análise das imagens. As GPUs (unidades de processamento gráfico) são processadores maciçamente paralelos, contendo centenas ou até milhares de unidades de processamento. Essas unidades são bem menos complexas quando comparadas às CPUs, mas por estarem em grande número apresentam elevado poder computacional, principalmente se a tarefa a ser executada apresenta baixa necessidade de controle de fluxo em relação ao número de operações lógicas e aritméticas (Silva, 2014). Uma vez que este é o caso de parte do processamento das imagens de ovitrampas, é interessante utilizar o processamento paralelo da GPU. Para a criação de aplicações na GPU, pode-se utilizar a ferramenta CUDA (Compute Unified Device Architecture) (NVIDIA, 2007). O CUDA permite que o programador defina funções especiais, chamadas kernels, as quais são executadas em paralelo na GPU. O fluxo do programa é controlado pela CPU, que executa trechos de código sequencialmente. O paralelismo se dá quando a CPU ativa a GPU realizando uma chamada de kernel. Assim, para paralelizar a análise das imagens utilizando CUDA, criou-se um kernel que processa um único pixel da imagem e realiza as duas primeiras etapas do processamento: prepara a imagem para a limiarização (neste trabalho, esta etapa consistiu apenas em selecionar a componente R da imagem, mas há outras possibilidades de processamentos mais complexos, envolvendo a aplicação de filtros ou conversão de sistemas de cores, cuja eficiência varia de acordo com a imagem) e aplica a limiarização em si, binarizando a imagem. A CPU então lança o kernel uma vez para cada pixel na imagem, e estas execuções ocorrem em paralelo nas threads da GPU. Similarmente, para a última etapa, referente à contagem do número de pixels brancos, pode-se criar um kernel que processa um único pixel e atualiza uma variável global caso este pixel seja branco. Esta atualização é feita utilizando o método CUDA atomicAdd, que permite alterar o valor de uma variável compartilhada por várias threads sem que haja condição de corrida. Já na etapa de eliminação de artefatos, foi utilizado um algoritmo que identifica áreas conexas de pixels brancos. Este algoritmo é mais complexo que o processamento das outras etapas, com mais controle de fluxo e dependência de processamento (os pixels não podem ser processados independentemente como nas outras etapas). Assim, nesta etapa manteve-se o processamento sequencial na CPU. Resultados e Discussão Esta seção apresenta os resultados obtidos aplicando o algoritmo sequencial e o algoritmo paralelo com CUDA em 5 imagens de ovitrampas diferentes. O algoritmo obteve erro médio de 18,7% na contagem de ovos. A tabela 1 apresenta compara a média dos tempos de execução obtidos na versão sequencial e na versão em CUDA. As implementações foram executadas, respectivamente, em um processador i7 com 8 GB de memória RAM e em uma placa gráfica GeForce GT 630M. Tabela 1 – Comparação dos resultados observados na implementação sequencial e paralela. Versão Sequencial CUDA Leitura da imagem 21,1 ms 45,2 ms Etapas 1 e 2 (paralelo) 3,5 ms 0,025 ms Etapas 3 e 4 (sequencial) 4,1 ms 4,8 ms Tempo Total 28,8 ms 50,0 ms Observa-se que as etapas 1 e 2 do processamento executaram consideravelmente mais rápido na GPU, demonstrando o poder paralelo da mesma bem como a natureza paralela destas etapas do processamento. Entretanto, observa-se que há um custo adicional associado à versão com CUDA na etapa de leitura da imagem, referente à alocação e transferência de memória entre CPU e GPU. Este custo resultou em um tempo total de execução maior para a versão paralela do que para a versão sequencial, uma vez que o processamento necessário nestes testes foi baixo. Isso se deve, em parte, à qualidade média das imagens (cerca de 700x700 pixels). Com imagens em maior qualidade, espera-se que o overhead causado pela transferência de memória seja compensado pelo menor tempo de execução nas regiões paralelas do código. Outros fatores que influenciaram o tempo total são o fato da placa gráfica utilizada para rodar as execuções ser uma placa com capacidade de processamento limitada, uma vez que é uma placa de um computador pessoal. Por fim, o overhead pode diminuir caso sejam processadas diversas imagens em uma só execução do programa, uma vez que a memória teria que ser alocada na GPU apenas uma vez (neste trabalho, o programa executava uma imagem por vez). Conclusões A computação paralela pode ser empregada quando se depara com problemas que requerem grande capacidade de processamento. Considerando a contagem automática de ovos de Aedes Aegypti em ovitrampas, observa-se que o processamento necessário para realizar esta contagem contém etapas de natureza paralela e que, em particular, se encaixam no modelo de programação paralela das GPUs. Observou-se que a implementação em CUDA diminuiu o tempo de execução de boa parte do processamento, mas ressalta-se que dividir um problema para ser resolvido paralelamente geralmente implica um custo adicional; para que haja ganho no tempo de execução, é necessário que este custo seja compensado pelo menor tempo de processamento dos trechos paralelos do código. Agradecimentos Ao MEC-SESU, pelo financiamento deste projeto de iniciação científica a partir do Programa de Educação Tutorial (PET). Referências NVIDIA (2007). CUDA C Programming Guide. http://docs.nvidia.com/cuda/cuda-cprogramming-guide. Acesso em 4 de agosto de 2016. Portela, N.M. (2009). Contagem automática de ovos de Aedes Aegypti em imagens de ovitrampas. Dissertação de Mestrado, Programa de Pós-Graduação Engenharia da Computação, Universidade de Pernambuco. Silva, C. (2014). Unidades de Processamento Gráfico – GPUs. In Silva, C., Programação Genética Maciçamente Paralela em GPUs (pp. 47-53). Rio de Janeiro: Pontifícia Universidade Católica do Rio de Janeiro.