Lab17 - Mediapipe
Mediapipe¶
Objetivos da aula:
- Apresentar e aplicar a biblioteca
mediapipe
Mediapipe é uma biblioteca de processamento de mídia de código aberto desenvolvida pelo Google, que fornece uma ampla variedade de algoritmos e ferramentas de visão computacional para análise de dados em tempo real.
A biblioteca é implementada em C++ e Python, com suporte para processamento em CPU e GPU.
Entre as funcionalidades oferecidas pela biblioteca Mediapipe, destacam-se a detecção de keypoints
, tracking
, classificação de gestos
, reconhecimento facial
, pose estimation
, detecção de objetos
e segmentação de imagem
.
A implementação desses algoritmos é feita utilizando técnicas de aprendizado de máquina e redes neurais profundas, incluindo redes neurais convolucionais e redes de grafos.
Instalação¶
A instalação é simples. Mas pode acontecer incompatibilidade de versões entre o python e algumas dependencias. Caso não consiga instalar via pip
será necessário investigar o erro para entender o que precisa ser ajustado na instalação.
No meu caso, usando Mac M2, estou usando:
- python 3.9.6
- mediapipe==0.10.9
## instalação via pip
#!pip install mediapipe==0.10.9
Primeiros passos¶
O site oficial da documentação do Mediapipe é o https://mediapipe.dev/.
Já existe bastante conteúdo contendo informações detalhadas sobre como utilizar cada uma das funcionalidades da biblioteca, incluindo tutoriais em vídeo e em texto, exemplos de código, e muito mais.
Além disso, a página oferece uma ampla variedade de recursos adicionais, como fóruns de discussão, bibliotecas de modelos pré-treinados, e outros materiais úteis para desenvolvedores de visão computacional.
Face¶
O Mediapipe face mesh
é um recurso da biblioteca Mediapipe que permite a detecção e rastreamento de faces.
import mediapipe as mp
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Configurações de desenho
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_face_mesh = mp.solutions.face_mesh
# Crie uma instância do objeto FaceMesh
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=True,
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5)
file = 'lena.png'
# Leia o arquivo de imagem com cv2 e converta de BGR para RGB
image = cv2.imread(file)
results = face_mesh.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
face_found = results.multi_face_landmarks
print(f'foram encontradas: {len(face_found)} faces na imagem')
if face_found:
# Crie uma cópia da imagem
annotated_image = image.copy()
# Desenha as landmarks e conexões
mp_drawing.draw_landmarks(
image=annotated_image,
landmark_list=results.multi_face_landmarks[0],
connections=mp_face_mesh.FACEMESH_TESSELATION,
landmark_drawing_spec=None,
connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_tesselation_style())
# Plota a imagem
plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()
# Não se esqueça de liberar os recursos do objeto face_mesh quando terminar
# face_mesh.close()
I0000 00:00:1712871282.566201 1 gl_context.cc:344] GL version: 2.1 (2.1 Metal - 88), renderer: Apple M2
foram encontradas: 1 faces na imagem
desafio1¶
Faça os ajustes para o código rodar com webcam.
# seu código aqui...
Desafio 2¶
Implemente uma solução que detecta se a pessoa está de olhos abertos ou fechados.
# seu código aqui...
Tracking de mão¶
O Mediapipe Hand Tracking
é um recurso da biblioteca Mediapipe que permite a detecção e rastreamento das mãos em tempo real, a partir de uma entrada de vídeo ou imagem.
Esse recurso utiliza uma rede neural
que é treinada
para reconhecer pontos de referência nas mãos, como a base dos dedos, pontas dos dedos e pulso.
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
cap = cv2.VideoCapture(0)
with mp_hands.Hands(min_detection_confidence=0.8, min_tracking_confidence=0.5) as hands:
while cap.isOpened():
ret, frame = cap.read()
# BGR 2 RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Flip on horizontal
image = cv2.flip(image, 1)
# Set flag
image.flags.writeable = False
# Detections
results = hands.process(image)
# Set flag to true
image.flags.writeable = True
# RGB 2 BGR
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# Rendering results
if results.multi_hand_landmarks:
for num, hand in enumerate(results.multi_hand_landmarks):
mp_drawing.draw_landmarks(image, hand, mp_hands.HAND_CONNECTIONS,
mp_drawing.DrawingSpec(color=(121, 22, 76), thickness=2, circle_radius=4),
mp_drawing.DrawingSpec(color=(250, 44, 250), thickness=2, circle_radius=2),
)
cv2.imshow('Hand Tracking', image)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
I0000 00:00:1712871632.333893 1 gl_context.cc:344] GL version: 2.1 (2.1 Metal - 88), renderer: Apple M2 2024-04-11 18:40:32.487 Python[40047:7578102] WARNING: Secure coding is automatically enabled for restorable state! However, not on all supported macOS versions of this application. Opt-in to secure coding explicitly by implementing NSApplicationDelegate.applicationSupportsSecureRestorableState:.
contagem dos dedos¶
adaptado de: https://github.com/ANANTH-SWAMY/NUMBER-DETECTION-WITH-MEDIAPIPE
import cv2
import mediapipe
import time
ctime=0
ptime=0
cap=cv2.VideoCapture(0)
medhands=mediapipe.solutions.hands
hands=medhands.Hands(max_num_hands=1,min_detection_confidence=0.7)
draw=mediapipe.solutions.drawing_utils
while True:
success, img=cap.read() #pega um frame da imagem
img = cv2.flip(img,1) # inverte a imagem
imgrgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#realiza a detecção da mão na imagem
res = hands.process(imgrgb)
lmlist=[]
tipids=[4,8,12,16,20] # lista com as pontas dos dedos
#desenha no canto da tela um retangulo, os numeros vão aparecer aqui
cv2.rectangle(img,(20,350),(90,440),(0,255,204),cv2.FILLED)
cv2.rectangle(img,(20,350),(90,440),(0,0,0),5)
## se detectar alguma mão entra no if
if res.multi_hand_landmarks:
for handlms in res.multi_hand_landmarks:
for id,lm in enumerate(handlms.landmark):
h,w,c= img.shape
cx,cy=int(lm.x * w) , int(lm.y * h)
lmlist.append([id,cx,cy])
if len(lmlist) != 0 and len(lmlist)==21:
fingerlist=[]
#thumb and dealing with flipping of hands
if lmlist[12][1] > lmlist[20][1]:
if lmlist[tipids[0]][1] > lmlist[tipids[0]-1][1]:
fingerlist.append(1)
else:
fingerlist.append(0)
else:
if lmlist[tipids[0]][1] < lmlist[tipids[0]-1][1]:
fingerlist.append(1)
else:
fingerlist.append(0)
#others
for id in range (1,5):
if lmlist[tipids[id]][2] < lmlist[tipids[id]-2][2]:
fingerlist.append(1)
else:
fingerlist.append(0)
if len(fingerlist)!=0: # se a lista for diferente de zero então
fingercount=fingerlist.count(1) # conta quantidade de dedos
# escreve na tela a quantidade detectada
cv2.putText(img,str(fingercount),(25,430),cv2.FONT_HERSHEY_PLAIN,6,(0,0,0),5)
#change color of points and lines
draw.draw_landmarks(img,handlms,medhands.HAND_CONNECTIONS,draw.DrawingSpec(color=(0,255,204),thickness=2,circle_radius=2),draw.DrawingSpec(color=(0,0,0),thickness=2,circle_radius=3))
cv2.imshow("hand gestures",img)
#press q to quit
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
I0000 00:00:1712871645.820581 1 gl_context.cc:344] GL version: 2.1 (2.1 Metal - 88), renderer: Apple M2
Desafio 3¶
O mediapipe possui um modo para detecção de pose, o dense pose. Implemente uma solução que realiza