2.1 – Detecção de movimento com Python e OpenCV

Esse tutorial objetiva mostrar como detectar movimentos usando Python e OpenCV. A detecção é feita através da comparação de imagens capturadas da webcam.

O primeiro passo está em capturar e mostrar a imagem da webcam e isso é feito através do código abaixo. O código instancia o uso da webcam e cria uma janela para que posteriormente seja inserida as capturas da webcam nessa janela. No laço de repetição se pega uma imagem da webcam e depois se mostra a imagem na janela. Para sair da aplicação foi configurado o uso da tecla ‘q’.

import cv2
webcam   = cv2.VideoCapture(0) #instancia o uso da webcam
janela   = "Tela de captura"
cv2.namedWindow(janela, cv2.CV_WINDOW_AUTOSIZE) #cria uma janela
while True:
  s, imagem = webcam.read() #pega efeticamente a imagem da webcam
  cv2.imshow(janela,imagem) #mostra a imagem captura na janela
  
  #o trecho seguinte é apenas para parar o código e fechar a janela
  if cv2.waitKey(1) & 0xFF == ord('q'):
    cv2.destroyWindow(janela)
    break

print "Fim"

O princípio da identificação de movimentos é capturar um frame e compará-lo com o frame anterior subtraindo os pixels de uma imagem da outra. Sendo assim, todas as imagem que estiverem iguais irão se anular. Como as imagem que estarão iguais são as que não mudaram de lugar, isso acaba mostrando apenas os locais onde alguma mudança (movimento) aconteceu.

A OpenCV oferece uma função que subtrai duas imagens, é a absdiff(). A função recebe dois array (a imagem é um array bidimensional) e retorna sua diferença absoluta. Também usaremos a função bitwise_and() para alcançar o resultado final na diferenciação das imagens. Esses dois métodos estão inseridos na função calculaDiferenca() do código a seguir.

Além da função adicionada no código foram adicionadas as linhas 11,12 e 13 que criam variáveis para armazenar 3 frames capturados e que serão utilizados na comparação da função criada. Inicialmente os três frames terão a mesma imagem, se diferenciamento a partir da terceira captura. São armazenados o último frame (frame atual), o penúltimo frame e o antepenúltimo frame. Veja que a captura da webcam é alterada para uma imagem em preto e branco através da função cv2.cvtColor() com o segundo parâmetro cv2.COLOR_RGB2GRAY.

Foram utilizadas as comparações com 3 frames, mas seria possível utilizar apenas os dois último frames, mas com os 3 frames o resultado é melhor. Caso opte por utilizar apenas 2 frames, a função calculaDiferenca()  pode calcular apenas o valor de d2 e retorná-lo.

Já no laço de repetição está sendo feita a atualização dos 3 frames de imagem. O antepenúltimo frame passa a conter a imagem do penúltimo, assim como o penúltimo passa a conter o frame que era o atual e o frame atual é atualizado com uma nova imagem capturada da webcam.

import cv2

def calculaDiferenca(img1, img2, img3):
  d1 = cv2.absdiff(img3, img2)
  d2 = cv2.absdiff(img2, img1)
  return cv2.bitwise_and(d1, d2)

webcam = cv2.VideoCapture(0) #instancia o uso da webcam
janela = "Tela de captura"
cv2.namedWindow(janela, cv2.CV_WINDOW_AUTOSIZE) #cria uma janela

#faz a leitura inicial de imagens
ultima        = cv2.cvtColor(webcam.read()[1], cv2.COLOR_RGB2GRAY)
penultima     = ultima
antepenultima = ultima

while True:
  antepenultima = penultima
  penultima     = ultima
  ultima        = cv2.cvtColor(webcam.read()[1], cv2.COLOR_RGB2GRAY)

  cv2.imshow(janela, calculaDiferenca(antepenultima,penultima,ultima))
  
  if cv2.waitKey(1) & 0xFF == ord('q'):
    cv2.destroyWindow(janela)
    break

print "Fim"

FAZER UM VIDEO PARA MOSTRAR COMO FICOU

Para determinar a “quantidade” de movimento que está acontecendo é possível, dentro do laço de repetição, mostrar uma soma de todos os pixels através  da instrução sum(sum(imagem)). Ao visualizar a diferença nos valores você vai perceber que a diferença não é tão grande. Isso porque a imagem ficou em escala de cinza e isso dificulta essa identificação. adicionar uma nova instrução para aumentar a diferença dos valores.

Altere a função calculaDifereca() adicionando a operação de threshold() da OpenCV. A função espera como primeiro parâmetro a imagem que será utilizada e em seguida o valor má

http://opencvpython.blogspot.com.br/2013/05/thresholding.html

http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#threshold

def calculaDiferenca(img1, img2, img3):
  d1 = cv2.absdiff(img3, img2)
  d2 = cv2.absdiff(img2, img1)
  imagem = cv2.bitwise_and(d1, d2)
  s,imagem = cv2.threshold(imagem, 35, 255, cv2.THRESH_BINARY)
  return imagem

 

MOSTRAR GANHOS E DESTAQUE ONDE ESTÁ O MOVIMENTO – vira outro artigo

Referências

http://www.steinm.com/blog/motion-detection-webcam-python-opencv-differential-images/
http://docs.opencv.org/master/modules/core/doc/operations_on_arrays.html?highlight=absdiff
http://opencvpython.blogspot.com.br/2013/05/thresholding.html
http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#threshold

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.