Reconhecimento Facial com Python

Diandra Rocha
CWI Software
Published in
5 min readJun 7, 2019

Afinal, as tecnologias de reconhecimento facial são realmente acessíveis para desenvolvimento e uso diário?

Qual o problema?

Hoje, para acionar as portas dos andares do prédio, temos um acionador (isso mesmo — o botãozinho) ou leitores como crachá ou digital. Essas opções são pouco otimizadas pelos contratempos de termos que apertar o botão e de não garantir a entrada somente de pessoal autorizado dentro dos andares. Já os leitores inteligentes nos dão essa segunda garantia, porém tem um custo elevado de obtenção e instalação. E se pudéssemos apenas olhar para uma câmera e abrir a porta, com grande agilidade e a segurança de que a porta só se abrirá se já conhecer nossos rostos?

Planejando a solução

First things first: Qual a diferença entre detecção facial e reconhecimento facial?

Elementar, meu caro Watson: Dentro do âmbito das tecnologias que foram utilizadas neste projeto, detectar um rosto em uma imagem (seja estática ou em streaming) é apenas determinar se há uma ou mais faces na imagem e entre quais pontos estão localizadas. Todavia, reconhecer um rosto é fazer uso de fórmulas para determinar a distância entre pontos predeterminados (como distância entre os olhos, nariz, boca) do rosto já detectado, assim podendo comparar com outra foto e dizer, com um certo grau de precisão, se trata-se ou não do mesmo rosto.

Reconhecimento facial vs. Detecção facial

Reconhecimento dos pontos de referência faciais
Detecção facial

Atualmente, Python é a sétima linguagem (entre programação e marcação) mais utilizada no mundo e a terceira mais amada, segundo o Stack Overflow. Essa enorme popularidade não vem à toa: Python é extremamente versátil, multiplataforma e, o melhor de tudo, tem uma vasta gama de libs e frameworks para os mais diversos fins, incluindo análise de imagens.

Dentro das libs disponíveis, a escolhida foi a face_recognition. Alguns dos motivos que embasaram a decisão foram: simplicidade na utilização, com diversos exemplos de uso; possibilidade de implementação em Python; uso direto na linha de comando ou até mesmo instalação no Raspberry Pi; somados à sua natureza open source, o que permitiu maior exploração do código fonte. Entretanto, não é multiplataforma — atualmente, só tem suporte oficial no Linux. Porém, alguns aventureiros ousaram tentar instalar no Windows e obtiveram sucesso.

Okay, mas como funciona?

A face_recognition é baseada na união de 3 libs principais: dlib, pillow e numpy.

Dlib é a encarregada do trabalho mais árduo: é ela que detecta o rosto na imagem e gera os encodings, que são codificações únicas pelas quais um rosto pode ser identificado, sendo auxiliada por numpy e o módulo de imagem do pillow para realizar as operações na foto convertida em arrays específicos, por meio de três objetos principais:

1º - Um objeto detector, instância de get_frontal_face_detector, criado pela própria lib, cuja missão é encontrar todos os rostos em uma imagem.

face_detection.py

A detecção facial da dlib se baseia na técnica "Histogram of Oriented Gradients " (HOG), que tem a filosofia de dividir para conquistar, traçando os cálculos por áreas chamadas de células para ponderar, normalizar e chegar a um resultado final.

2º - Um objeto predictor, construído pelo shape_predictor, recebe em seu construtor um modelo baseado na quantidade de pontos que deverá procurar na imagem, para que a inteligência de detecção HOG seja treinada por isso. Para este projeto, usamos o arquivo dat que contém o treinamento baseado em 5 pontos, treinado por 7198 faces, feito por um entusiasta e que pode ser encontrado aqui.

face_landmarks.py

3º - Por último, mas não menos importante, o objeto face_encoder, que é criado a partir do construtor de face_recognition_model_v1, especifica como calcular, utilizando uma deep learning treinada pelo arquivo fornecido (cerca de 3 milhões de rostos), um array de 128 posições contendo uma descrição específica do rosto encontrado pelo predictor. Estes encodings são um representante único do rosto mapeado e o resultado final do reconhecimento facial. É por eles que podemos comparar dois diferentes rostos e dizer a proximidade entre seus arrays descritivos.

face_encode.py

Depois de entender passo a passo como funciona a face_recognition por dentro, está na hora de utilizá-la:

face_recognition_with_lib.py

Até então, entendemos o que são e como são gerados esses encodings. Agora, vamos entender como eles podem ser comparados entre si.

A comparação dos arrays de 128 posições da lib é baseada na distância euclidiana entre dois pontos:

Para este cálculo observamos retornos, em geral, em valores entre 0 e 1: quanto mais alto o valor, mais próximos são os rostos. A lib interpreta este valor dentro de um fator pré estipulado de margem de erro aceitável (0.4), retornando true ou false.

face_comparison.py

Para o projeto, como um dos objetivos era realizar a operação de comparação com a melhor performance possível, abandonamos este método para utilizar uma procedure com um cálculo adaptado no banco de dados PostgreSQL. Nesta, removemos a parte de raiz do cálculo para reduzir o custo de processamento da operação, invertendo o fator de comparação pensando em comparações realizadas com uma grande quantidade de rostos.

Final Facts

A tecnologia provou-se muito eficaz em cumprir aquilo que se propõe a fazer: reconhecimento facial com precisão e velocidade satisfatória. Com scripts simples e grande variedade de formas de uso, a lib possibilita uma miríade de possibilidades para aperfeiçoar processos e suprir necessidades já existentes. Os exemplos utilizados nas imagens acima podem ser encontrados neste repositório.

Para disponibilizar serviços de reconhecimento facial de forma RESTful foi construída uma API Python utilizando Flask. Foram desenvolvidas duas versões, utilizando duas abordagens diferentes: um aplicativo Android, para também cadastrar os usuários e seus rostos, e a versão final utilizando Raspberry Pi e um monitor que pode ser encontrada de forma itinerante pela CWI, ambos aliando detecção facial ao processo de reconhecimento.

A solução Android foi deixada em segundo plano devido à interação necessária entre servidor de processamento e device, o que torna essa solução mais lenta. Já a segunda proposta se apresenta mais ágil contando com o processamento centralizado no próprio Raspberry Pi, não necessitando de conexão externa e feedback visual via monitor.

Atualmente, o aplicativo desenvolvido é utilizado apenas para fazer o cadastro dos rostos dos usuários que serão autorizados pelo Raspberry Pi a entrar no andar. Os rostos armazenados na base alimentada pelo app são transferidos para o sistema de reconhecimento via integração SSIS (SQL Server Integration Services) toda manhã.

O projeto já tem uma versão piloto que encontra-se atualmente no segundo andar. Para testar, basta se cadastrar usando o tablet do Núcleo de Tecnologia.

--

--