Introdução

Detecção de movimento é um adendo importante no processamento digital de imagens. É necessário para monitorar e analisar ambientes em geral. A atividade se propõe a implementar um programa que tenha a capacidade de detectar algum movimento a partir de imagens obtidas por uma webcam. As estratégias utilizadas para conseguir esse objetivo serão apresentadas a seguir.

Desenvolvimento da atividade

A partir da análise e comparação de histograma é possível verificar se um objeto se movimentou em cena. A comparação é simples: uma vez que os níveis de cor ou tom de cinza entre duas imagens consecutivas apresentarem uma diferença significativa, isso pode ser interpretado como uma movimentação ocorrida na imagem capturada.

No código abaixo podemos ver como o processo foi desenvolvido por meio de comentários.

Código no OpenCV

Listagem 1. detector_movimento.cpp
#include <iostream>
#include <unistd.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, char** argv){
  	Mat image,image2;

  	//Variáveis necessárias para a construção do histograma
  	int 		 histSize 	= 64;                   //Número de subdivisões horizontais
  	float 		 range[] 	= { 0, 256 };           //Limites inferior e superior do histograma
  	const float* histRange 	= { range };
  	Mat histograma, histograma2;                    //Objeto onde o histograma será armazenado
  	Mat histImage,histImage2;

  	double alert, media;

  	VideoCapture cap;
  	cap.open(0);

  	if(!cap.isOpened()){
    	cout << "Erro de abertura da webcam.";
    	return -1;
    }

	while(1){

   		cap >> image;
   		flip(image,image,1);                          //espelhar a tela pra deixar a visualização mais fiel da realidade
   		cvtColor(image,image,CV_BGR2GRAY);            //Convertendo RGB para Escala de Cinza
   		usleep(10000);                                //10ms delay

   		cap >> image2;
   		flip(image2,image2,1);                        //espelhar a tela pra deixar a visualização mais fiel da realidade
   		cvtColor(image2,image2,CV_BGR2GRAY);          //Convertendo RGB para Escala de Cinza

   		//Reinicializando as imagens dos histogramas
   		histImage.setTo( Scalar(0));
   		histImage2.setTo(Scalar(0));

   		//Calculando o histograma das imagens
   		calcHist(&image, 1, 0, Mat(), histograma , 1, &histSize, &histRange, true, false);
   		calcHist(&image2, 1, 0, Mat(), histograma2, 1, &histSize, &histRange, true, false);

      //Realizando a comparação entre os dois histogramas obtidos
   		alert = compareHist(histograma, histograma2,CV_COMP_CORREL);

      //Definição do limiar de diferença entre os histogramas
   		media = 0.999;

      //Apresentação dos resultados
      if(alert < media)
        cout << alert << " MOVIMENTO" << endl;

      namedWindow("entrada", CV_WINDOW_KEEPRATIO);
      imshow("entrada", image);
	  if(waitKey(10) >= 0) break;
	}

  	imwrite("saida.png",image2);
  	imwrite("entrada.png",image);
  	return 0;
}

O programa trata-se basicamente da captura de duas imagens e a realização da comparação entre elas. A captura das imagens são separadas por um intervalo de 10 ms (através da função usleep). Com as imagens capturadas, o cálculo do histograma de ambas as imagens é feito pela função calcHist().

Com o histograma de cada uma, a comparação é então realizada pela função compareHist(). Essa função retorna um número resultante de algum método de comparação entre os dados dos histogramas. Nesse programa, foi utilizado o método de correlação para a comparação.

No método de correlação, quando duas imagens são iguais, o valor retornado pelo método é 1. E quando as imagens apressentam histogramas bem diferentes, o valor retornado é mais próximo de zero. Poderíamos então imaginar que, para detectar um movimento, basta testar se o valor retornado é diferente de 1, e então concluir que houve movimento. No entanto, isso não é aplicável devido à existência de ruído na captura da câmera, que faria o programa detectar movimento a todo momento, mesmo sem haver movimento.

Assim, foi observado o valor médio retornado pela função enquanto a câmera apontava para uma cena imóvel. Esse valor encontrou-se por volta de 0.999. Com isso, a mensagem de movimentação é enviada apenas quando o resultado da comparação é menor que 0.999.

Resultados

Em desenvolvimento…​

O resultado obtido pode ser visualizado no seguinte vídeo:

640
Figura 1. Imagem capturada pela webcam

O método de comparação de histogramas não é o mais eficiente para a detecção de movimentos, pois é necessário achar um valor ideal para o limiar que indica que houve movimento, sendo a determinação desse limiar bastante empírica. No entanto, para movimentos mais bruscos, o método funciona de maneira satisfatória.