##
## Detecção de Movimento em vídeo utilizando 2 possívels estratégias: "Background adaptativo" ou "diferenças entre 3 quadros".
##
## Parametros de entrada: 
##	  caminhoEntrada-> path para quadros de entrada (numerados sequencialmente como em 0001.jpg
##	  caminhoSaida -> path para diretorio onde serão salvos os quadros resultantes do processamento
##	  quadros -> numero de quadros a processar a partir do quadro inicial do video
##	  modo: 0 (background adaptativo), ou 1 (diferenças entre 3 quadros)
##	  limiar: limiar para detecção de movimento (tipicamente na faixa de 20-50)
##	  offset: utilizado no modo 0, numero de quadros no passado e no futuro para diferença com o quadro corrente
##	  alfa: utilizado no modo 1, numero float entre 0 e 1 (alfa=0 recai em subtração simples de background e 
##              alfa=1 recai em diferença entre quadros adjacentes)
## 
##  Exemplos de uso: 
##                   processaVideo('frames_new/LeftBag_PickedUp ','out/',100, 1, 35, 10, 0);
##                   processaVideo('frames_new/LeftBag_PickedUp ','out/',100, 0, 35,  0, 1);
##
function processaVideo(caminhoEntrada, caminhoSaida, quadros, modo, limiar, offset, alfa)

   BG=int16(imread([caminhoEntrada, '0001.jpg'])); # background adaptativo (inicialmente primeiro quadro do video)
   BG=(BG(:,:,1)+BG(:,:,2)+BG(:,:,3))/3; # conversão de cores para tons de cinza

   # Ajusta quadro inicial e final do processamento em função do modo de operação.
   if(modo==1) # detecção de movimento por diferenças entre 3 quadros 
      iInicial=offset+1;
      iFinal=quadros-offset;  
   else if(modo==0) # detecção de movimento utilizando background adaptativo
		  iInicial=2;
		  iFinal=quadros;
        else
		  'Modo invalido, exiting....'
		  exit(1);
	    endif
   endif


   for i=iInicial:1:iFinal; # laço de varredura dos quadros de video

     # leitura do i-ésimo quadro do video
     numeroArquivo=sprintf("%04d",i);
     quadroCorrente=int16(imread([caminhoEntrada,numeroArquivo,'.jpg']));
     quadroCorrente=(quadroCorrente(:,:,1)+quadroCorrente(:,:,2)+quadroCorrente(:,:,3))/3;
     
     
     if(modo==1) # detecção de movimento por diferenças entre 3 quadros 

        # Leitura do quadro i-offset (passado)
        numeroArquivo=sprintf("%04d",i-offset);
        quadroPassado=int16(imread([caminhoEntrada, numeroArquivo,'.jpg']));
        quadroPassado=(quadroPassado(:,:,1)+quadroPassado(:,:,2)+quadroPassado(:,:,3))/3;

        # Leitura do quadro i+offset (Futuro)
        numeroArquivo=sprintf("%04d",i+offset);
        quadroFuturo=int16(imread([caminhoEntrada, numeroArquivo,'.jpg']));
        quadroFuturo=(quadroFuturo(:,:,1)+quadroFuturo(:,:,2)+quadroFuturo(:,:,3))/3;

        difPassado=abs(quadroCorrente-quadroPassado);
        difFuturo=abs(quadroCorrente-quadroFuturo);
        diferenca=min(difPassado,difFuturo); # realiza o "e" lógico entre as diferenças através da operação MIN
     else  
       diferenca = abs(quadroCorrente-BG);
       BG = alfa * quadroCorrente + (1-alfa)*BG; # atualização do background
     endif
     
     G=fspecial('gaussian');
     diferenca=filter2(G,diferenca) # suavizacao utilizando Gaussiana para reduzir ruídos

     output=uint8(255*(diferenca>limiar)); # limiariza a diferenca

     imwrite(output,[caminhoSaida,numeroArquivo,'.jpg']); # grava no disco a saida da função de detecção de movimento
  endfor

endfunction 
