OpenCV - tutorial deteção de blobs e movimento - parte 2
Continuando o meu relato de pesquisa com o OpenCV e Processing…
Depois de testar e constatar que o OpenCV estava capturando corretamente a imagem da minha webcam, chagou a hora de ver como interpretar as imagens. Logo de início fui atrás de como capturar Blobs via OpenCV. Blobs? O que são blobs?… Bem, pelo que entendi, são chamados “blobs” áreas da imagem que se destacam pelo contraste de cores, geralmente contraste entre pontos claros, e escuros (brilho e sombra), mas também é possível fazer seleção por cores específicas.
Com uma rápida consultada na documentação da biblioteca OpenCV para o Processing (veja os itens na coluna à esquerda), há um bom exemplo de como os blobs funcionam. Pelo exemplo o que acontece é o seguinte; Quando chamada a função blobs(), do objeto opencv, o resultado é um array de objetos tipo Blob, que por sua vez, possuem lá seus recursos. Então eu fui xeretar; E a partir do último código comecei a fazer o seguinte (após a função image(), dentro da função draw()):
opencv.threshold(50);
Blob[] blobs = opencv.blobs(20, width*height/2, 10, true, OpenCV.MAX_VERTICES);
println(blobs.length);
O que fiz foi pedir a detecção de Blobs, que ficaram armazenados no array ‘blobs’, e na seqüencia apenas imprimo no console a quantidade de blobs detetados ( detetados: nova forma de detectados, após o acordo ortográfico =P). Logo de cara, reparei que para a deteção de blobs é necessário um certo tratamento na imagem, no caso o “threshold”. Para quem não conhece tratamento de imagens, esse efeito reduz a quantidade de cores de uma imagem por aproximação, e com isso aumenta os contrastes, veja:

Imagens sem, e com, aplicação de filtro “threshold”. Essa configuração é importante para adequar sua captação de blobs à iluminação da sua “cena”.
[…]
Sem a aplicação desse tratamento parece que a deteção de Blobs, não funciona. =P Não gostei disso.
Continuando, fui fazer como no exemplo da documentação e desenhar os blobs na tela para vê-los. E isso é possível se fazer com diferentes informações contidas nos blobs. Para começar mais simples, decidi desenhar na tela o centro do blob, veja na documentação que cada blob possui um ponto chamado ‘centroid’. Então vou usá-lo para desenhar uma elipse no centro de cada blob:
opencv.threshold(100); //tratamento da imagem
Blob[] blobs = opencv.blobs(20, width*height/2, 10, true, OpenCV.MAX_VERTICES);
//desenhar os blobs existentes
for( int i=0; i<blobs.length; i++ ) {
fill(200,50,10);
ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);
fill(255);
}
Repare que, obviamente, temos que iterar (com o loop for) por cada blob que está na lista de “blobs”, para desenhar cada um dos “centroids”. Outra opção possível, é fazer como no exemplo, desenhar o contorno de cada blob. Veja abaixo, como fazer isso junto com o desenho dos “centroids”, apenas alterando o loop ‘for’:
//desenho dos contronos dos blobs
beginShape();
for( int j=0 ; j<blobs[i].points.length ; j++){
vertex( blobs[i].points[j].x, blobs[i].points[j].y );
}
endShape(CLOSE);
//desenho dos centroids
fill(200,50,10);
ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);
fill(255);
}
Novamente na documentação há a descrição dos ‘points’, que é uma lista dos pontos de compõe o contorno do blob, assim podemos usar essa informação para criar um segundo loop onde desenhamos os pontos como um ’shape’ de fundo branco. Veja como deve ficar:
Além disso outros pontos devem ser observados, em especial as opções para a função blobs(). Naqueles parâmetros é onde se pode configurar melhor a captura desses blobs, lembre-se: SEMPRE OLHE E LEIA A DOCUMENTAÇÃO! Fazendo algumas alterações os resultados podem lhe ser mais interessantes.
Devo confessar que não fiquei muito feliz com a forma do OpenCV fazer a deteção de blobs, e me lembrei da biblioteca BlobDetection, que me trouxeram resultados melhores (em minha opinião). Logo, optei por utilizá-la para esse trabalho. Futuramente vamos falar sobre ela, mas antes vamos falar sobre deteção de movimentos via OpenCV. Mas fica para os próximos textos.
Até.
PS: O código completo é
import hypermedia.video.*;
//Instanciar um objeto OpenCV
OpenCV opencv;
//Configurar a tela do nosso programa
void setup(){
size(640,480); //tamanho da tela
opencv = new OpenCV(this); //construir objeto OpenCV
opencv.capture(640,480); //inicia captura de vídeo
}
void draw(){
opencv.read(); //faz a leitura das imagens da câmera
image(opencv.image(), 0,0);//desenha a imagem na tela
//Iniciar captura de blobs
opencv.threshold(100); //tratamento da imagem
Blob[] blobs = opencv.blobs(200, width*height/2, 10, false, OpenCV.MAX_VERTICES/4);
//desenhar os blobs existentes
for( int i=0; i<blobs.length; i++ ) {
//desenho dos contronos dos blobs
beginShape();
for( int j=0 ; j<blobs[i].points.length ; j++){
vertex( blobs[i].points[j].x, blobs[i].points[j].y );
}
endShape(CLOSE);
//desenho dos centroids
fill(200,50,10);
ellipse(blobs[i].centroid.x, blobs[i].centroid.y, 5,5);
fill(255);
}
}