sexta-feira, 7 de setembro de 2018

Detecção e reconhecimento facial para webcams


Já apresentei um tutorial de reconhecimento facial, inclusive utilizando Raspberry PI, mas agora, vou mostrar um outro exemplo, construído do zero, para uso em webcams. Ele é capaz de detectar vários rostos em uma imagem e reconhecer cada um deles. A foto acima é um teste feito com uma webcam.




Montar um projeto destes exige várias atividades separadas:

  1. Criar um mecanismo capaz de detectar rostos em imagens;
  2. Criar uma rede CNN e treina-la para reconhecer alguns rostos;
  3. Criar um programa capaz de capturar imagens e submete-las ao modelo treinado.
Todo o código fonte deste projeto está no Github: https://github.com/cleuton/FaceGuard/tree/master/FaceRec

Como utilizar este exemplo

Baixe as imagens para as pastas: "raw" e "rawvalidation" e execute o programa "trainCNN.py", que treinará sua rede e salvará um arquivo de modelo "faces_saved.h5". Ao treinar a rede, copie os nomes das pessoas, na ordem correta. O programa vai exibir algo assim: 

['Abdullah_Gul', 'Al_Gore', 'cleuton', 'Bill_Clinton']

No meu caso, usei imagens de 3 pessoas, coletadas do dataset público "Labeled Faces in the Wild" e inseri umas 20 fotos minhas, com meu rosto em várias posições diferentes.

O programa "trainCNN.py" vai ajustar as imagens da pasta "raw" e copiar para "train" e "test". As da pasta "rawvalidation" serão ajustadas e copiadas para a pasta "val", para serem utilizadas em uma predição. É importante que as imagens utilizadas contenham um só rosto! Examine as imagens e, se houver mais de um rosto, descarte.

O programa "predict.py" captura uma imagem da sua webcam e tenta reconhecer os rostos presentes, gerando um resultado como o da figura topo deste artigo:


Os rostos aparecerão demarcados e, se o programa reconhecer o rosto, o nome aparecerá no canto superior esquerdo do quadrado.

O programa "predict.py" pode funcionar de duas maneiras: Capturando uma imagem ou lendo um arquivo gravado. Dentro do código há comentários indicando como você pode alternar o funcionamento (é só comentar / descomentar um determinado bloco de código).

Sim, você pode usar para reconhecer as pessoas da sua família, da sua equipe, da sua empresa etc.

Detectando rostos em imagens

Detectar rostos em imagens é uma questão de observar os "landmarks" que identificam rostos (olhos, nariz, boca etc). A biblioteca Dlib é perfeitamente capaz de fazer isto. Há dois objetos do Dlib que podem nos ajudar muito: 
  • dlib.get_frontal_face_detector(): Capaz de detectar rostos vistos de frente;
  • dlib.shape_predictor(): Capaz de predizer a posição de um rosto e seus pontos de referência;
Poderíamos partir diretamente para uma rede neural, como eu fiz com o exemplo dos cães e gatos, mas, para obter uma boa acurácia em reconhecimento facial, é preciso colocar os rostos em uma posição mais favorável para treinar e fazer predições. 

Se você quiser se aprofundar sobre este assunto, há um excelente tutorial de  Adrian Rosebrock sobre detecção de faces, de onde peguei exemplos para montar meu projeto. 

Uma rede CNN

Este é o terceiro exemplo que eu mostro, utilizando uma rede CNN - Convolutional Neural Network para reconhecimento de imagens. 

Rede neural convolucional ou CNN, é uma técnica de deep learning muito utilizada para reconhecimento de imagens, requer pouco ou nenhum pré-processamento de imagens. 

Em uma CNN, as camadas de neurônios não estão totalmente conectadas, e são divididas em áreas separadas da imagem, cada uma processando um pedaço específico. 

Podemos ter uma CNN (parcialmente conectada) para aprender sobre as características dos objetos, ligada a um grupo de camadas totalmente conectadas (fully connected) para classificar os objetos de acordo com as características aprendidas.


Uma operação de convolução é como resumir uma vizinhança de pixels em um único valor, resumindo as características mais importantes. Podemos detectar curvas, cantos etc. Quando agregamos vários filtros de convolução a uma CNN, podemos detectar várias características diferentes da imagem.

Neste exemplo, eu utilizei a API Keras, com o backend TensorFlow para montar minha CNN. 

Se quiser saber mais sobre este assunto, leia meus livros de Data Science (o Banner está no topo desta página). 

Nosso modelo é composto por várias camadas convolucionais e densas (totalmente conectadas): 

x = conv3x3(inputs, 32)
x = conv3x3(x, 32)
x = MaxPooling2D(pool_size=(2,2))(x) 
x = conv3x3(x, 64)
x = conv3x3(x, 64)
x = MaxPooling2D(pool_size=(2,2))(x) 
x = conv3x3(x, 128)
x = MaxPooling2D(pool_size=(2,2))(x) 
x = Flatten()(x)
x = Dense(128, activation="relu")(x)

Cada função "conv3x3" gera uma camada convolucional com filtro de 3 por 3 pixels. Cada camada "MaxPolling2D" serve para reduzir o resultado de camadas convolucionais, gerando uma rede menor. Ao, final, eu "achato" as dimensões das imagens e passo para uma camada de rede totalmente conectada, que vai classificar cada imagem. 

É o mesmo modelo que eu utilizei no exemplo de gatos e cachorros, e funcionou bem. 

A preparação das imagens


Antes de submeter as imagens ao modelo, eu tenho que fazer algumas preparações: 
  • Converter para grayscale. A princípio, eu poderia usar as imagens coloridas, mas isso representaria 3 dimensões de cor; 
  • Expandir o vetor de imagem, de modo a colocar a intensidade do pixel em uma dimensão separada;
  • Detectar os rostos, extrair sub imagens para cada um deles, rotacionar e cortar, preenchendo para ficar como um quadrado de 64 x 64;
Esta preparação, com um cuidadoso estudo de camadas e quantidade de épocas de treinamento, me permitiu alcançar 90% de acurácia, o que foi muito bom, em se tratando de rostos de pessoas, em várias posições.







Nenhum comentário:

Postar um comentário