Detecção Facial com Deep Learning
Detecção facial com deep learning é uma das aplicações mais importantes de visão computacional. Ela consiste em detectar a presença de rostos em imagens ou vídeos. Após ser detectada, a face localizada pode ser usada em tarefas de reconhecimento de identidade, análise de emoções, identificação de gênero, pose, etc.
A detecção facial tem inúmeras aplicações. Obviamente, muitas delas são na área de segurança, mas outros campos também podem se beneficiar bastante dessa técnica.
![Detecção facial com Python](https://sp-ao.shortpixel.ai/client/to_auto,q_glossy,ret_img,w_400,h_400/https://www.aprendizartificial.com/wp-content/uploads/2024/06/fig8.jpg)
Desenvolver um modelo de detecção facial do zero pode ser uma tarefa difícil. Ela envolve acesso a dados e recursos computacionais caros. Para contornar esse problema, uma solução simples e barata é o uso de modelos pré-treinados.
Existem vários modelos classificadores pré-treinados disponíveis para detecção facial. Em posts anteriores, usamos o classificador Haar Cascade e o excelente YOLO Faces. Neste post, apresentaremos outra opção: a rede neural do tipo deep learning MTCNN (Multi-Task Cascaded Convolutional Neural Network).
Bibliotecas
pip install mtcnn numpy opencv-python Pillow
O MTCNN roda em cima do Keras. Portanto, na primeira vez que você o usar, é provável que precise instalar o Keras ou TensorFlow se eles não estiverem em seu sistema.
Detecção Facial em Código
Para usar o MTCNN, primeiro fazemos as importações necessárias e iniciamos o classificador.
import cv2
from mtcnn.mtcnn import MTCNN
import numpy as np
from PIL import Image
detector = MTCNN()
Faremos a detecção em imagens primeiro e depois em vídeo. Para realizar a detecção em uma imagem, basta abri-la com Pillow. Ela deve ser convertida para RGB para garantir bons resultados. O classificador também funciona melhor se elas estiverem no formato de NumPy array.
file = 'LOCAL DA SUA IMAGEM'
image = Image.open(file)
image = image.convert('RGB')
img = np.asarray(image)
Em seguida, aplicamos o classificador.
faces = detector.detect_faces(img)
Quando o classificador detecta rostos, ele retorna uma lista com várias informações, como mostrado no exemplo abaixo:
[{'box': [557, 161, 35, 50], 'confidence': 0.9327843189239502, 'keypoints': {'left_eye': (564, 179), 'right_eye': (581, 181), 'nose': (567, 189), 'mouth_left': (562, 199), 'mouth_right': (577, 202)}}]
Essa lista contém os dados para definir caixas delimitadoras localizando os rostos na imagem, o intervalo de confiança da classificação feita e dados adicionais indicando a posição de pontos-chave dos rostos (boca, nariz e olhos). Usaremos essas informações a seguir.
Caixas Delimitadoras
Para adicionar as caixas delimitadoras numa imagem com rostos, usamos um for loop.
if faces:
for face in faces:
x1, y1, width, height = face['box'] # pega as coordenadas das caixas delimitadoras
prob = round(face['confidence'], 3)
if prob > 0.8:
x1, y1 = abs(x1), abs(y1)
x2, y2 = x1 + abs(width), y1 + abs(height)
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2) # usa as coordenadas para desenhar caixas
cv2.putText(img, str(
prob), (x1, y2), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
img = Image.fromarray(np.uint8(img)).convert('RGB') # reconverte imagem
img.save('nova_imagem.jpg') # salva imagem
Basicamente, o loop parte dos dados encontrados pelo classificador e usa o OpenCV para desenhar uma caixa delimitadora nas coordenadas onde cada rosto foi localizado. No trecho de código acima, também adicionamos os intervalos de confiança para cada rosto detectado. Após a execução do loop, salvamos a imagem com as caixas delimitadoras. Veja alguns exemplos de resultados abaixo.
Pontos-Chave Faciais
Para adicionar outros dados retornados pelo classificador (localização de olhos, nariz e boca), precisamos expandir um pouco nosso for loop como mostrado a seguir. As expansões estão com as linhas marcadas:
if faces:
for face in faces:
print(face)
x1, y1, width, height = face['box']
nose = face['keypoints']['nose'] # nariz
mouth_right = face['keypoints']['mouth_right'] # ponto boca direita
mouth_left = face['keypoints']['mouth_left'] # ponto boca esquerda
right_eye = face['keypoints']['right_eye'] # olho direito
left_eye = face['keypoints']['left_eye'] # olho esquerdo
prob = round(face['confidence'], 3)
if prob > 0.8:
x1, y1 = abs(x1), abs(y1)
x2, y2 = x1 + abs(width), y1 + abs(height)
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2)
cv2.circle(img, mouth_right, 5, (255, 255, 255), -1)
cv2.circle(img, mouth_left, 5, (255, 255, 255), -1)
cv2.circle(img, nose, 5, (255, 255, 255), -1)
cv2.circle(img, right_eye, 5, (255, 255, 255), -1)
cv2.circle(img, left_eye, 5, (255, 255, 255), -1)
cv2.putText(img, str(
prob), (x1, y2), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
img = Image.fromarray(np.uint8(img)).convert('RGB')
img.save('nova_imagem.jpg') # salva imagem
E aqui estão alguns resultados com caixas delimitadoras e pontos-chave marcando olhos, nariz e pontos laterais da boca de cada rosto detectado.
Detecção Facial em Video
Evidentemente, além de fazer detecção facial em imagens, podemos fazê-las em vídeos. Para isso, passamos o código definido anteriormente para dentro de uma função. Ela tem algumas modificações (linha 4) no início para converter os frames do vídeo para o formato apropriado.
def detecta_faces(frame):
"""Detecta faces com deep learning"""
image = Image.fromarray(np.uint8(frame)).convert('RGB')
img = np.asarray(image)
faces = detector.detect_faces(img)
if faces:
for face in faces:
print(face)
x1, y1, width, height = face['box']
nose = face['keypoints']['nose']
mouth_right = face['keypoints']['mouth_right']
mouth_left = face['keypoints']['mouth_left']
right_eye = face['keypoints']['right_eye']
left_eye = face['keypoints']['left_eye']
prob = round(face['confidence'], 3)
if prob > 0.8:
x1, y1 = abs(x1), abs(y1)
x2, y2 = x1 + abs(width), y1 + abs(height)
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 255, 255), 2)
cv2.circle(img, mouth_right, 5, (255, 255, 255), -1)
cv2.circle(img, mouth_left, 5, (255, 255, 255), -1)
cv2.circle(img, nose, 5, (255, 255, 255), -1)
cv2.circle(img, right_eye, 5, (255, 255, 255), -1)
cv2.circle(img, left_eye, 5, (255, 255, 255), -1)
cv2.putText(img, str(
prob), (x1, y2), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
return img
Depois, precisamos escrever um trecho de código para realizar a leitura do vídeo e aplicar a função.
path_name = 'LOCAL_DO_SEU_VIDEO_AQUI.mp4'
# realiza leitura de vídeo com OpenCV
video_cap = cv2.VideoCapture(path_name)
while True:
ret, frame = video_cap.read()
controlkey = cv2.waitKey(1)
if not ret:
break
detections = detecta_faces(frame) # detecta faces em cada frame
cv2.imshow("Frame", detections) # exibe vídeo
if cv2.waitKey(1) == ord("q"):
break
video_cap.release()
cv2.destroyAllWindows()
Abaixo mostramos um pequeno resultado.
![detecta faces com Python](https://sp-ao.shortpixel.ai/client/to_auto,q_glossy,ret_img,w_460,h_259/https://www.aprendizartificial.com/wp-content/uploads/2024/06/detecta_faces.gif)