OpenCV - tutorial deteção de blobs e movimento - parte 3
… Continuando dos posts anteriores …
Agora com a captação a imagem da câmera funcionando, e fazendo a leitura dos blobs, cabem algumas considerações sobre os resultados obtidos do sistema. A primeira coisa que se nota é que, a deteção de blobs ocorre em todos os frames da captação de vídeo. Isso não é, necessariamente, o ideal, dependendo do projeto. Afinal na minha idéia, só me interessa verificar o que se move. Com esse comportamento da deteção de blobs, repara-se que mesmo algumas variações de iluminação são o suficiente para o OpenCV ler novos blobs.
Lendo um pouco a documentação do OpenCV e vendo alguns exemplos, reparei na função absDiff(), que trabalha em conjunto com a função remember(). O que elas fazem é “lembrar” ( remember() ) o frame anterior, calcular a diferença ( absDiff() ) para o frame atual, e gerar uma imagem com essa diferença. Ótimo, esse seria um grande passo para facilitar a deteção, exclusiva, de movimentos.
Para estudar exclusivamente esse recurso, fiz o seguinte código:
import hypermedia.video.*;
//Instanciar um objeto OpenCV
OpenCV opencv;
//Imagem que captura o "Movimento"
PImage movement;
//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
}
//Execução do software
void draw(){
opencvAction();
}
//Ações do OpenCV
void opencvAction(){
opencv.read();
opencv.absDiff();
movement = opencv.image();
image( movement, 0, 0 );
opencv.remember();
}
O resultado foi esse:
Só um comentário sobre o código em sí: Eu coloquei o trabalho do OpenCV em uma função, chamada opencvAction(), para organizar melhor o código, porque daqui em diante, o código vai crescer em tamanho, e já é bom fazer as coisas organizadinhas para facilitar correções futuras.
Mas o fato realmente “empolgante”, é que com o uso desses recursos obtemos uma imagem que possui apenas a informação de modificações entre o frame anterior e o atual! Vejamos a função opencvAction():
- Na primeira linha da função: lemos o conteúdo da câmera.
- Na segunda linha, chamamos a função absDiff(), para calcular a diferença entre os frames.
- Na terceira linha, guardamos a imagem resultante da diferença no objeto “movement” - observar que esse é um objeto da classe PImage
- Na quarta linha, desenhamos a imagem da diferença (movement) na tela.
- Na quinta linha, chamamos a função remember(), para que no próximo frame, o OpenCV, tenha essa imagem para comparar com a próxima.
Com isso feito, fiz o próximo teste, que seria, fazer a deteção de blobs, apenas na imagem resultante da deteção de movimentos, veja o código abaixo: (Obs: apenas acrescentei a função detetarBlobs() )
import hypermedia.video.*;
//Instanciar um objeto OpenCV
OpenCV opencv;
//Imagem que captura o "Movimento"
PImage movement;
//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
}
//Execução do software
void draw(){
opencvAction();
detetarBlobs();
}
//Ações do OpenCV
void opencvAction(){
opencv.read();
//opencv.convert(OpenCV.GRAY);
opencv.absDiff();
movement = opencv.image();
image( movement, 0, 0 );
opencv.remember();
}
void detetarBlobs(){
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);
}
}
O resultado foi este:
Com essa base, já é possível fazer uma deteção de movimento bem melhor. Temos a imagem “resultante” do movimento; fazendo a deteção de blobs conseguimos isolar dessa imagem as “coisas” que se movem em frente a câmera; Com os blobs calculados, podemos gerar um ponto médio desse deslocamento, fazendo uma média aritmética simples dos pontos “centroids” de cada blob: soma-se os ‘centroid’ de cada blob, e divide-se pela quantidade de blobs.
Bem, é claro que essa última sugestão - na verdade todas as sugestões que dei aqui - dependem do seu projeto, da sua idéia.
Basicamente esse post meio tutorial, meio relato, acaba aqui. Vou escrever um próximo, falando da classe BlobDetection, que chamou muito minha atenção, pela qualidade da deteção de blobs que ela oferece. Ao menos para o meu projeto é melhor que a opção disponível padrão do OpenCV. Mas vale dizer que ambas fazem a mesma coisa, da mesma forma.
até mais.

