Home > Processing, Tutoriais > OpenCV - tutorial deteção de blobs e movimento - parte 3

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:

//importar biblioteca OpenCV

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() )

//importar biblioteca OpenCV
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&lt;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.

Processing, Tutoriais , ,

  1. Valdemir
    June 2nd, 2010 at 00:08 | #1

    Paulo como eu faço para criar um botão quando vc habilitar a camera em opencv, ou carrega uma imagem na camera de um objeto na camera?
    att,
    valdemir

  2. Angelo (Soulless-BR)
    July 13th, 2010 at 15:10 | #2

    Fala Paulo, tudo bom cara? Seguinte estive pesquisando detecção de faces com Python e acabei caindo na biblioteca OpenCV e encontrei o seu Blog. Vi que você utiliza essa biblioteca no Processing e fiquei com uma curiosidade. O processamento do seu programa fica alto? Eu fiz um em Python e ele detecta a face normalmente, porém, o nível de processamento em um core 2 duo com 4gb fica próximo ou acima dos 80%. Teria alguma dica? Obrigado. Abraços.

  3. Leandro
    July 26th, 2010 at 23:33 | #3

    Olá Paulo!!

    estou tentando rodar esse teu exemplo, com processing 1.2.1, opencv 1.0 no windows 7, sei que teu exemplo foi feito no linux, gostaria de saber se acontecia este erro pra você também. Segue o erro:

    Error while starting capture : device 0
    OpenCV could not define source dimensions.

    processing.app.debug.RunnerException: NullPointerException
    at processing.app.Sketch.placeException(Sketch.java:1543)
    at processing.app.debug.Runner.findException(Runner.java:582)
    at processing.app.debug.Runner.reportException(Runner.java:558)
    at processing.app.debug.Runner.exception(Runner.java:498)
    at processing.app.debug.EventThread.exceptionEvent(EventThread.java:367)
    at processing.app.debug.EventThread.handleEvent(EventThread.java:255)
    at processing.app.debug.EventThread.run(EventThread.java:89)
    Exception in thread “Animation Thread” java.lang.NullPointerException
    at processing.core.PGraphics.image(Unknown Source)
    at processing.core.PApplet.image(Unknown Source)
    at sketch_jul26b.opencvAction(sketch_jul26b.java:64)
    at sketch_jul26b.draw(sketch_jul26b.java:50)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:619)

    desde já agradeco.

  4. Admin
    July 27th, 2010 at 18:43 | #4

    @Leandro

    Bem, eu não cheguei a testar esses programas com OpenCV no Windows… Mas pelo erro, parece que o OpenCV não está conseguindo achar a sua Webcam. Eu chegeui a enfrentar problemas no Linux com OpenCV. No meu caso, um modelo de webcam que eu tinha em mãos parecia ser incompatível.

    Isso e pareceu absurdo, mas foi a única explicação que achei, e para resolver, usei outro modelo de webcam, aí funcionou. E para fazer a coisa rolar com aquele modelo de webcam, eu usei outra biblioteca de captura de vídeo, a GSVideo, e com ela, usei também a Blob Detection.

    Tá certo que com isso, não tinha mais certos recursos que o OpenCV oferece, mas…

    Eu não sei como o OpenCV captura o sinal da cam. O Processing “normal”, usa o QuickTime para isso, tanto no Mac, quanto no Windows. E para Linux há o GSVideo, que usa o GStreamer, um framework multimídia usado como padrão em várias distros de Linux.
    Talvês a soluçnao desse problema esteja em você conferir a instalação do QuickTime, e do JVM. Ainda se não der, dê uma olhada no GSVideo, que também está disponível para Windows.

    Abraço,

  1. No trackbacks yet.