Lab07 - Traking de objetos e movimento
Objetivos da aula:
- Conhecer e praticar tracking de objetos em movimento
Background Subtraction¶
A intuição de como realizar essa tarefa nós já sabemso, basicamente iremos comparar duas imagem: a de referência do fundo com uma segunda imagem de teste. O resultado irá ressaltar a diferença da imagem.
####----- FAZENDO O DOWNLOAD DAS IMAGENS DO RESPOSITÓRIO, APENAS PARA FACILITAR -----#####
## Vou fazer o download das imagens do laboratório diretamente do repositório para ficar mais facil....
import requests
import os
# Define o laboratório
laboratorio = 'lab07' ### altere para o laboratório desejado
diretorio = 'lab_images' ### altere para o diretório que deseja salvar as imagens
# Download de um arquivo
def download_file(url, destination):
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(destination, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)
print(f"Baixado: {destination}")
else:
print(f"Erro ao baixar {url}")
# Monta a URL completa
api_url = "https://api.github.com/repos/arnaldojr/cognitivecomputing/contents/material/aulas/PDI/"
url_completa = api_url + laboratorio
print(f"Fazendo o download de: {url_completa}")
# checa se a URL está acessível
response = requests.get(url_completa)
if response.status_code != 200:
raise Exception(f"Erro ao acessar o repositório: {response.status_code}")
files = response.json()
# Faz o download de cada arquivo
os.makedirs(diretorio, exist_ok=True) # Cria a pasta downloads
for file in files:
file_name = file['name']
if file_name.endswith(('.png', '.jpg', '.jpeg', '.mp4')): # Adicione mais extensões se necessário
file_url = file['download_url']
destination = os.path.join(diretorio, file_name)
download_file(file_url, destination)
print(f"Download concluído. Arquivos salvos na pasta {diretorio}.")
Fazendo o download de: https://api.github.com/repos/arnaldojr/cognitivecomputing/contents/material/aulas/PDI/lab07 Baixado: lab_images/people-walking.mp4 Baixado: lab_images/sala2.jpg Baixado: lab_images/sala3.jpg Download concluído. Arquivos salvos na pasta lab_images.
DESAFIO 1¶
Implemente um código (simples) que seja capaz de realizar a subtração das imagens e detectar movimento.
Dica: você pode usar operações cv2.absdiff(img1, img2) e se necessário realizar uma operação morfologia (abertura/ fechamento, dilatação/erosão) para reduzir o ruido. O resultado deve ser parecido com a imagem "sala_res.png".
USE COMO IMAGENS DE ENTRADA AS OPÇÕES:¶
- SALA, SALA1, SALA2, SALA3
%matplotlib inline
import cv2
from matplotlib import pyplot as plt
import numpy as np
img = cv2.imread('sala_res.png')
plt.figure(figsize = (10,10))
plt.imshow(img); plt.show();
# Implemente seu código.....
Background Subtraction em videos¶
O desafio acima foi fácil! pois existe uma imagem de fundo sozinha, como uma imagem da sala sem vazia. Basta subtrair a nova imagem do plano de fundo. Você obtém os objetos de primeiro plano sozinhos.
Mas, na maioria dos casos, você pode não ter essa imagem, então precisamos extrair o plano de fundo de qualquer imagem que tenhamos. Aiiiiii complica as coisas.
Na OpenCV podemos implementar isso por meio de dois algoritmos. O primeiro é createBackgroundSubtractorKNN() ou createBackgroundSubtractorMOG2(). Isso cria um objeto subtrator de fundo por K-Nearest Neighbor (KNN) ou Mixture of Gaussians (MOG2) . Então, podemos chamar a função apply() com o objeto para obter a máscara do primeiro plano. Podemos exibir diretamente a máscara de primeiro plano em tempo real (com video :)).
Referência da documentação: https://docs.opencv.org/master/de/de1/group__video__motion.html#gac9be925771f805b6fdb614ec2292006d
Executar video no jupyter notebook normalmente da problema.¶
Existem algumas formas de rodar, mas pode ficar delay.
Sugestão: Escreva um script e execute direto pelo terminal.
###### leia com atenção!!! este código roda em sua máquina local.
import numpy as np
import cv2
#carrega o video
cap = cv2.VideoCapture('people-walking.mp4')
# Cria a subtração do fundo
fgbg = cv2.createBackgroundSubtractorMOG2(history=500, varThreshold=16, detectShadows=True)
# fgbg = cv2.createBackgroundSubtractorKNN()
while(1):
ret, frame = cap.read()
if not ret:
break
# Aplica a mascara no frame recebido
fgmask = fgbg.apply(frame)
cv2.imshow('fgmask',frame)
cv2.imshow('frame',fgmask)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
O Kernel deu pane ao executar o código na célula atual ou em uma célula anterior. Analise o código nas células para identificar uma possível causa da pane. Clique <a href='https://aka.ms/vscodeJupyterKernelCrash'>aqui</a> para obter mais informações. Consulte Jupyter <a href='command:jupyter.viewOutput'>log</a> para obter mais detalhes.
DESAFIO 2¶
Crie um programa python e execute o código acima. O objetivo, nesse primeiro momento, é se familiarizar com a estrutura do código, para isso, explore os metodos MOG2 e KNN e observe os resultados.
Explore os parametros da função:
history: O numero de frames usado para construir o modelo estatisco da fundo. Quando menor mais rapido.
dist2Threshold: é o limiar definido para saber se o pixel pertence ao fundo ou não da imagem. Quando menor mais sensivel.
detectShadows : Se True, a sombra (shadows) vai aparecer em cinza na imagem.
DESAFIO 3¶
Faça um programa que detecta o movimento das pessoas andando na rua e marca com um boundBox (retangulo) o que foi detectado.
Instruções/Dicas:
Use 'people-walking.mp4' como video para os testes.
Lembre-se do que já estudamos para remover ruido, realçar contorno, detectar bordas....
Sempre
Leia a documentação: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.htmlUse a função cv2.boundingRect() para desenhar o retangulo.
O resultado dever ser semelhante ao do video.
from IPython.display import Image
Image(open('pessoas-gif.gif','rb').read())