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