Serviço de Detecção Facial MTCNN com Flask

Introdução à Detecção Facial com MTCNN e Flask A detecção de faces é uma tarefa fundamental em visão computacional, com aplicações em segurança, organização de fotos e interação humano-computador. O MTCNN (Multi-task Cascaded Convolutional Networks) é um modelo popular e eficiente para essa finalidade. Este artigo demonstra como integrar o MTCNN em um serviço web usando o framework Flask, permitindo a detecção de faces em imagens locais ou remotas.

Detecção de Faces em Imagens Locais Para começar, vamos exemplificar a detecção de faces em uma imagem armazenada localmente. O MTCNN retorna uma lista de dicionários, onde cada dicionário representa um rosto detectado, incluindo suas coordenadas (box), nível de confiança (confidence) e pontos-chave (keypoints) como olhos, nariz e boca.

import cv2
from mtcnn.mtcnn import MTCNN

# Carrega a imagem e converte para RGB (MTCNN espera RGB)
caminho_imagem = './face.png'
imagem_rgb = cv2.cvtColor(cv2.imread(caminho_imagem), cv2.COLOR_BGR2RGB)

# Inicializa o detector MTCNN
detector_facial = MTCNN()
resultados_detecao = detector_facial.detect_faces(imagem_rgb)

# Imprime os detalhes dos rostos detectados
print(resultados_detecao)


O resultado da detecção é uma estrutura como a seguinte, mostrando as caixas delimitadoras, a confiança e os pontos-chave para cada rosto:

[{'box': [283, 295, 43, 49], 'confidence': 0.9999926090240479, 'keypoints': {'left_eye': (297, 311), 'right_eye': (317, 311), 'nose': (308, 322), 'mouth_left': (299, 332), 'mouth_right': (316, 332)}}, 
{'box': [748, 436, 49, 54], 'confidence': 0.9999852180480957, 'keypoints': {'left_eye': (765, 456), 'right_eye': (786, 456), 'nose': (776, 467), 'mouth_left': (767, 477), 'mouth_right': (783, 477)}}]
# ... (conteúdo omitido para brevidade)


Visualizando os Resultados da Detecção Para verificar visualmente as detecções, é útil desenhar os retângulos delimitadores e os pontos-chave na imagem original. O OpenCV é empregado para essas operações gráficas e para salvar a imagem processada.

import cv2
from mtcnn.mtcnn import MTCNN

caminho_imagem_entrada = './face.png'
imagem_com_deteccoes = cv2.cvtColor(cv2.imread(caminho_imagem_entrada), cv2.COLOR_BGR2RGB)

detector_rostos = MTCNN()
deteccoes_encontradas = detector_rostos.detect_faces(imagem_com_deteccoes)

for rosto_info in deteccoes_encontradas:
    x_pos, y_pos, largura, altura = rosto_info['box']
    # Desenha o retângulo delimitador
    cv2.rectangle(imagem_com_deteccoes, (x_pos, y_pos), (x_pos + largura, y_pos + altura), (0, 255, 0), 2) # Cor verde
    # Adiciona a confiança
    cv2.putText(imagem_com_deteccoes, '{:.2f}'.format(rosto_info['confidence']), (x_pos, y_pos - 10), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) # Cor verde
    # Desenha os pontos-chave
    for ponto, coordenadas in rosto_info['keypoints'].items():
        cv2.circle(imagem_com_deteccoes, (coordenadas[0], coordenadas[1]), 5, (0, 0, 255), -1) # Cor azul, preenchido

# Converte de volta para BGR antes de salvar
imagem_final = cv2.cvtColor(imagem_com_deteccoes, cv2.COLOR_RGB2BGR)
cv2.imwrite('deteccoes_visuais.jpg', imagem_final)


Após executar este script, um arquivo deteccoes_visuais.jpg será gerado, exibindo os retângulos e pontos-chave sobre cada rosto detectado.

Detecção de Faces em Imagens Remotas (URLs) Um cenário comum é a necessidade de detectar faces em imagens acessíveis via URL. Para isso, utilizamos a biblioteca requests para baixar a imagem e numpy juntamente com opencv para processá-la em memória.

import cv2
from mtcnn.mtcnn import MTCNN
import requests
import numpy as np

url_da_imagem_remota = 'http://seu_servidor_de_imagens:8080/exemplo_rosto.jpg' # Substitua pela sua URL
response_imagem = requests.get(url_da_imagem_remota)

# Converte os bytes da imagem em um array numpy e decodifica com OpenCV
array_bytes_img = np.frombuffer(response_imagem.content, np.uint8)
imagem_decodificada = cv2.imdecode(array_bytes_img, cv2.IMREAD_COLOR)
imagem_processada_rgb = cv2.cvtColor(imagem_decodificada, cv2.COLOR_BGR2RGB)

detector_mtcnn_remoto = MTCNN()
rostos_encontrados = detector_mtcnn_remoto.detect_faces(imagem_processada_rgb)

print(rostos_encontrados)


O resultado será uma saída JSON similar à detecção de imagem local, mas para a imagem obtida da URL.

Construindo um Serviço Flask Básico Antes de integrar o MTCNN, vamos criar uma aplicação Flask simples. Isso serve como base para entender como os endpoints são definidos e como a aplicação pode ser executada.

from flask import Flask

# Inicializa a aplicação Flask
app_simples = Flask(__name__)

# Define uma rota padrão
@app_simples.route('/')
def mensagem_inicial():
    return 'Bem-vindo ao serviço Flask básico!'

# Inicia o servidor web
if __name__ == '__main__':
    app_simples.run(host='0.0.0.0', port=5000, debug=True) # debug=True para desenvolvimento


Ao executar este script, o Flask iniciará um servidor em http://0.0.0.0:5000/ (ou http://127.0.0.1:5000/), e acessar a URL no navegador retornará a mensagem "Bem-vindo ao serviço Flask básico!".

Integrando o MTCNN em um Serviço Flask Agora, combinaremos a funcionalidade de detecção de faces de URL com o framework Flask para criar uma API RESTful. Esta API receberá o nome de uma imagem (servida por um servidor de arquivos externo, como Nginx ou Apache) e retornará os resultados da detecção facial em formato JSON. from flask import Flask, jsonifyimport requestsimport osimport cv2import numpy as npfrom mtcnn.mtcnn import MTCNNapp_detector_facial = Flask(__name__)# O modelo MTCNN pode ser inicializado uma única vez para otimizar o desempenhomodelo_detector = MTCNN()# Define a URL base onde as imagens estão hospedadasURL_BASE_IMAGENS = 'http://seu_servidor_de_imagens:8080/' # Substitua pela sua URL basedef realizar_deteccao(nome_da_imagem: str): """ Realiza a detecção facial em uma imagem remota. """ url_completa_imagem = os.path.join(URL_BASE_IMAGENS, nome_da_imagem) try: resposta_get = requests.get(url_completa_imagem, timeout=10) # Adiciona timeout resposta_get.raise_for_status() # Lança exceções para status de erro HTTP dados_imagem_binarios = np.frombuffer(resposta_get.content, np.uint8) imagem_cv = cv2.imdecode(dados_imagem_binarios, cv2.IMREAD_COLOR) if imagem_cv is None: return None, "Não foi possível decodificar a imagem." imagem_rgb = cv2.cvtColor(imagem_cv, cv2.COLOR_BGR2RGB) rostos_identificados = modelo_detector.detect_faces(imagem_rgb) return rostos_identificados, None except requests.exceptions.RequestException as e: return None, f"Erro ao acessar a imagem: {e}" except Exception as e: return None, f"Erro interno de processamento: {e}"@app_detector_facial.route('/detectar_face/<nome_imagem_arquivo>')def endpoint_detecao_face(nome_imagem_arquivo): """ Endpoint para detectar faces em uma imagem remota e retornar JSON. """ deteccoes, erro = realizar_deteccao(nome_imagem_arquivo) if erro: return jsonify({'status': 'erro', 'mensagem': erro}), 500 return jsonify({'status': 'sucesso', 'deteccoes': deteccoes})if __name__ == '__main__': app_detector_facial.run(host='0.0.0.0', port=5001, debug=True)```<p>Neste código, o modelo MTCNN é instanciado uma única vez globalmente para evitar recargas desnecessárias, o que melhora o desempenho. O endpoint /detectar_face/<nome_imagem_arquivo></p></nome_imagem_arquivo> recebe o nome do arquivo da imagem como parte da URL e invoca a função realizar_deteccao. Os resultados são então retornados em formato JSON.

Consumindo o Serviço Flask com Python Para interagir com o serviço de detecção facial, podemos usar um script Python cliente que faz uma requisição HTTP GET ao endpoint do Flask. O cliente pode então processar os resultados JSON recebidos, por exemplo, desenhando as caixas delimitadoras na imagem original e salvando-a. import requests import numpy as np import cv2 import json

URL do seu serviço Flask de detecção facial

URL_SERVICO_FLASK = 'http://127.0.0.1:5001/detectar_face/exemplo_rosto.jpg' # Substitua pela sua URL

URL da imagem original para visualização local (pode ser a mesma URL base do servidor)

URL_IMAGEM_ORIGINAL = 'http://seu_servidor_de_imagens:8080/exemplo_rosto.jpg'

Faz a requisição ao serviço Flask

response_flask = requests.get(URL_SERVICO_FLASK) dados_deteccao = response_flask.json() # Assume que o Flask retorna JSON

print("Resultados da detecção recebidos do Flask:") print(json.dumps(dados_deteccao, indent=2))

--- Visualização local dos resultados ---

if dados_deteccao['status'] == 'sucesso':

Baixa a imagem original para desenhar as detecções

response_original = requests.get(URL_IMAGEM_ORIGINAL) array_bytes_img_original = np.frombuffer(response_original.content, np.uint8) imagem_para_desenhar = cv2.imdecode(array_bytes_img_original, cv2.IMREAD_COLOR)

if imagem_para_desenhar is not None: for info_rosto in dados_deteccao['deteccoes']: x, y, w, h = info_rosto['box'] cv2.rectangle(imagem_para_desenhar, (x, y), (x + w, y + h), (0, 255, 0), 2) # Verde cv2.putText(imagem_para_desenhar, '{:.2f}'.format(info_rosto['confidence']), (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) # Verde for ponto_chave, coords in info_rosto['keypoints'].items(): cv2.circle(imagem_para_desenhar, (coords[0], coords[1]), 5, (0, 0, 255), -1) # Azul

cv2.imwrite('imagem_com_deteccoes_remotas.jpg', imagem_para_desenhar) print("Imagem com detecções salvas como 'imagem_com_deteccoes_remotas.jpg'") else: print("Erro: Não foi possível carregar a imagem original para visualização.") else: print(f"Erro no serviço Flask: {dados_deteccao['mensagem']}")

Este script cliente primeiro consulta a API do Flask e depois, usando os dados de detecção retornados, carrega novamente a imagem original para desenhar as caixas delimitadoras e os pontos-chave, salvando a imagem resultante localmente.

Tags: Flask mtcnn detecção-facial OpenCV Python

Publicado em 8-3 00:17