segunda-feira, 10 de dezembro de 2007

Semana 21

Esta semana consegui voltar à carga.

Tal como já tinha ficado combinado, comecei a trabalhar com a webcam ligada ao computador.

Depois de alguma procura, consegui arranjar uma biblioteca que funcionasse com a maior parte das webcam's e comecei a fazer os primeiros testes.

Apliquei a biblioteca de processamento que já tinha vindo a contruir (ImageProcessorMobile) para o HTC, e esta funcionou bem. Tem como base a Compact Framework e por isso limita um pouco os calculos por não ter grande parte das funções.

Perdi mais de metade da semana de volta da detecção de objectos. Depois de procurar e ler alguns foruns da especialidade, a melhor opção pareceu-me seguir o que o Andrew tinha feito na biblioteca dele (aforge). O grande problema foi que eu tinha que por aquela funcao a funcionar, mas com a compact framework, o que implicava não usar alguns tipos de dados importantes.

Depois de falar com ele e tirar algumas duvidas e ao fim de bastantes tentativas consegui no final implementar um detector de objectos (blobcounter), que baseado numa imagem binarizada, identifica objectos de um dado tamanho (que podemos definir).

O algoritmo funciona bastante bem caso a imagem binariazada que lhe é passada tenha bem definidas as áreas a preto e branco. Quando a imagem não tem uma fronteira bem definida entre objectos é complicado para essa função detecta-los.

Ao detectar os objectos, estes são catalogados como rectângulos, que permite assim analisa-los relativamente à sua posição, extremos e tamanho.

Depois disto passei para o filtros de (uma determinada) cor. Este filtro funciona basicamente como um filtro de threshold, em que o que fica a branco é o que está dentro do valor de cor e a preto o que está fora desse valor.

Implementei uma função que permitia receber um valor de margem e que analisava um conjunto de 20 pixeis no centro da imagem, detectava a sua cor média e aplicava o dado filtro com base nessa cor. Para facilitar o processo, a imagem era convertida para preto e branco, donde apenas se extraia o valor do pixel da mesma (visto que os 3 pixeis têm o mesmo valor).

Comecei por aplicar um filtro de preto e branco básico, no qual o valor de um pixel cinzento = (r + g + b)/3. Isto trouxe bastantes problemas, pois o filtro detectava até 3 vezes na imagem uma cor diferente para cada valor. (por exemplo, tudo vermelho, ou tudo verde, ou tudo azul, ambos davam 255/3).

Para resolver isto apliquei um filtro de preto e branco RMY, em que cinzento = (r * 0.3 + g * 0.59 + b * 0.11). Isto melhorou o desempenho, no entanto o mesmo ainda só funciona bem em locais em que a iluminação não é muito intensa e em que haja uma grande diferença entre a cor do objecto a que queremos aplicar e a cor do fundo.

De seguida passei para a detecção de movimento. Comecei tal como sugerido por dividir a imagem em 4 partes e analisar a intensidade de luz em cada uma delas. Através da analise da movimentação dos histogramas tentava detectar para onde é que a imagem se tinha mexido.

Mesmo depois de ter criado vários filtros para limpar a imagem, como o filtro de erosão e o de pixelate, o resultado não foi o que esperava. A taxa de sucesso era baixa, e so funcionava em fundos escuros e com luz bastante controlada.

Passei para outra aproximação, que foi utilizar a detecção de objectos que já tinha feito e ver para onde o objecto se mexia. O algoritmo apesar de bastante simples, apenas analisa o objecto de maior tamanho, teve resultados muito satisfatórios.

Depois de ver isso resolvi então juntar ainda o filtro de cor a esse algoritmo e o resultado foi bastante bom. Nota-se que quando o filtro de cor é bem aplicado a detecção da movimentação do objecto é bastante mais precisa.

Consegui então chegar ao pretendido e ter um sistema que tem a funcionar, de um modo ainda simples, a detecção de objectos, como a detecção de movimentos, como a detecção de cores.

Para as proximas semanas tenho que juntar tudo isto num programa e tentar começar a melhora-lo.

Sem comentários: