Reconhecimento facial em tempo real com Raspberry Pi e OpenCV

Reconhecimento facial em tempo real com Raspberry Pi e OpenCV


O reconhecimento facial está se tornando cada vez mais popular e a maioria de nós já o usa sem perceber. Seja uma simples sugestão de tag do Facebook ou filtro Snapchat ou uma vigilância avançada de segurança de aeroporto, o Face Recognition já trabalhou sua mágica nisso. A China começou a usar o Reconhecimento Facial nas escolas para monitorar a frequência e o comportamento dos alunos. As lojas de varejo começaram a usar o Face Recognition para categorizar seus clientes e isolar pessoas com histórico de fraude. Com muito mais mudanças em andamento, não há dúvida de que essa tecnologia seria vista em todos os lugares no futuro próximo.

Neste tutorial, aprenderemos como podemos construir nosso próprio sistema de reconhecimento facial usando a biblioteca OpenCV no Raspberry Pi. A vantagem de instalar este sistema no Raspberry Pi portátil é que você pode instalá-lo em qualquer lugar para funcionar como sistema de vigilância. Como todos os sistemas de reconhecimento facial, o tutorial envolverá dois scripts python, um é um programa Trainer que irá analisar um conjunto de fotos de uma pessoa em particular e criar um conjunto de dados (arquivo YML). O segundo programa é o programa Recognizer que detecta um rosto e então usa este arquivo YML para reconhecer o rosto e mencionar o nome da pessoa. Ambos os programas que discutiremos aqui são para Raspberry Pi (Linux), mas também funcionarão em computadores Windows com pequenas alterações. Já temos uma série de tutoriais para iniciantes para começar a usar o OpenCV, você pode verificar todos os tutoriais do OpenCV aqui.


Pré-requisitos


Como dito anteriormente, usaremos a Biblioteca OpenCV para detectar e reconhecer rostos. Portanto, certifique-se de instalar a Biblioteca OpenCV no Pi antes de prosseguir com este tutorial. Além disso, alimente seu Pi com um adaptador 2A e conecte-o a um monitor de vídeo via cabo HDMI, pois não poderemos obter a saída de vídeo por meio de SSH.

Além disso, não vou explicar como exatamente o OpenCV funciona, se você estiver interessado em aprender o processamento de imagens, verifique os fundamentos do OpenCV e os tutoriais avançados de processamento de imagens. Você também pode aprender sobre contornos, detecção de blob, etc., neste tutorial de segmentação de imagens.


Como funciona o reconhecimento facial com OpenCV


Antes de começar, é importante entender que a Detecção de Rosto e o Reconhecimento de Rosto são duas coisas diferentes. Na detecção de rosto, apenas o rosto de uma pessoa é detectado, o software não terá ideia de quem é essa pessoa. No Face Recognition, o software não detectará apenas o rosto, mas também reconhecerá a pessoa. Agora, deve ficar claro que precisamos realizar a detecção de rosto antes de realizar o reconhecimento de rosto. Não seria possível para mim explicar como exatamente o OpenCV detecta um rosto ou qualquer outro objeto para esse assunto. Então, se você está curioso para saber, pode seguir este tutorial de Detecção de Objetos.

Um feed de vídeo de uma webcam nada mais é do que uma longa sequência de imagens estáticas sendo atualizadas uma após a outra. E cada uma dessas imagens é apenas uma coleção de pixels de diferentes valores reunidos em suas respectivas posições. Então, como um programa pode detectar um rosto a partir desses pixels e reconhecer ainda mais a pessoa nele? Existem muitos algoritmos por trás disso e tentar explicá-los está além do escopo deste artigo, mas como estamos usando a biblioteca OpenCV, é muito simples realizar o reconhecimento facial sem nos aprofundarmos nos conceitos


Detecção de rosto usando classificadores em cascata em OpenCV


Somente se formos capazes de detectar um rosto, seremos capazes de reconhecê-lo ou lembrá-lo. Para detectar um objeto como rosto, o OpenCV usa algo chamado Classificadores. Esses classificadores são conjuntos de dados pré-treinados (arquivo XML) que podem ser usados para detectar um determinado objeto em nosso caso, um rosto. Você pode aprender mais sobre classificadores de detecção de rosto aqui. Além de detectar o rosto, os classificadores podem detectar outros objetos como nariz, olhos, placa do veículo, sorriso, etc. A lista de classificadores de caso pode ser baixada do arquivo ZIP abaixo


Classificadores para detecção de objetos em Python


Alternativamente, o OpenCV também permite que você crie seu próprio classificador, que pode ser usado para detectar qualquer outro objeto em uma imagem, treinando seu classificador Cascade. Neste tutorial, usaremos um classificador chamado “haarcascade_frontalface_default.xml” que detectará o rosto de frente. Veremos mais sobre como usar os Classificadores na seção Programação.


Instalando os pacotes necessários


Certifique-se de que o pip esteja instalado e prossiga com a instalação dos seguintes pacotes.

Instalar dlib: Dlib é um kit de ferramentas para aplicativos de aprendizado de máquina e análise de dados do mundo real. Para instalar o dlib, basta digitar o seguinte comando no terminal



Pip install dlib


Isso deve instalar o dlib e quando for bem-sucedido, você obterá uma tela como esta.

Instalando pillow: Pillow também conhecido como PIL significa Python Imaging Library, que é usada para abrir, manipular e salvar imagens em diferentes formatos. Para instalar o PIL use o seguinte comando


Pip install pillow

Depois de instalado, você receberá uma mensagem de sucesso

Instale face_recognition: a biblioteca face_recognition para python é considerada a biblioteca mais simples para reconhecer e manipular faces. Estaremos usando esta biblioteca para treinar e reconhecer rostos. Para instalar esta biblioteca siga o comando


Pip install face_recognition –no –cache-dir

Quando instalado com sucesso, você deverá ver uma tela como a mostrada abaixo. A biblioteca é pesada e a maioria das pessoas enfrentará problemas de excesso de memória, portanto, usei o código “—no –cache-dir” para instalar a biblioteca sem salvar os arquivos de cache.


Configurando o diretório Face_Images com faces de exemplo


O diretório Face_Images mostrado acima deve ter subdiretórios com o nome da pessoa que deve ser reconhecida e algumas fotos de exemplo dela dentro dele. Por causa deste tutorial, tentei me reconhecer (Aswinth) e Elon Musk. Portanto, criei apenas dois subdiretórios com imagens como a mostrada abaixo.

Você deve renomear a pasta com o nome da pessoa que você está reconhecendo e também substituir as fotos por essa pessoa. Um mínimo de 5 fotos para cada pessoa parece funcionar bem. Porém, quanto maior for o número de pessoas, mais lento será o programa.


Programa de treinamento facial


Vamos dar uma olhada no programa Face_Traineer.py. O objetivo do programa é abrir todas as imagens do diretório Face_Images e pesquisar os rostos. Assim que o rosto é detectado, ele corta o rosto e o converte em tons de cinza e, em seguida, em uma matriz numpy, finalmente usamos a biblioteca face_recognition que instalamos anteriormente para treiná-lo e salvá-lo como um arquivo chamado face-trainner.yml. Os dados neste arquivo podem ser usados posteriormente para reconhecer os rostos. O programa completo do Trainer é fornecido no final, explicando aqui as linhas mais importantes.

Começamos o programa importando os módulos necessários. O módulo cv2 é usado para processamento de imagens, o numpy é usado para converter imagens em equivalentes matemáticos, o módulo os é usado para navegar pelos diretórios e o PIL é usado para lidar com imagens.


import cv2 #For Image processing

import numpy as np #For converting Images to Numerical array

import os #To handle directories

from PIL import Image #Pillow lib for handling images


Em seguida, temos que usar o classificador haarcascade_frontalface_default.xml para detectar os rostos nas imagens. Certifique-se de ter colocado este arquivo xml na pasta do projeto, caso contrário, ocorrerá um erro. Em seguida, usamos a variável de reconhecedor para criar um Reconhecedor de Face Histograma de Padrão Binário Local (LBPH).


face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

recognizer = cv2.createLBPHFaceRecognizer()


Então temos que entrar no diretório Face_Images para acessar as imagens dentro dele. Este diretório deve ser colocado dentro do seu diretório de trabalho atual (CWD). A linha a seguir é usada para acessar a pasta que é colocada no CWD.


Face_Images = os.path.join(os.getcwd(), "Face_Images") #Tell the program where we have saved the face images


Em seguida, usamos o for loops para entrar em cada subdiretório do diretório Face_Images e abrir todos os arquivos que terminam com jpeg, jpg ou png. O caminho de cada imagem é armazenado em uma variável chamada path e o nome da pasta (que será o nome da pessoa) na qual as imagens são colocadas são armazenados em uma variável chamada person_name.


for root, dirs, files in os.walk(Face_Images): #go to the face image directory

for file in files: #check every directory in it

if file.endswith("jpeg") or file.endswith("jpg") or file.endswith("png"): #for image files ending with jpeg,jpg or png

path = os.path.join(root, file)

person_name = os.path.basename(root)


Se o nome da pessoa mudou, incrementamos uma variável chamada Face_ID, isso nos ajudará a ter Face_ID diferente para pessoa diferente que usaremos posteriormente para identificar o nome da pessoa.


if pev_person_name!=person_name: #Check if the name of person has changed

Face_ID=Face_ID+1 #If yes increment the ID count

pev_person_name = person_name


Como sabemos, é muito mais fácil para o OpenCV trabalhar com imagens em tons de cinza do que com imagens coloridas, pois os valores BGR podem ser ignorados. Portanto, para reduzir os valores na imagem, nós a convertemos em tons de cinza e também redimensionamos a imagem para 550 para que todas as imagens permaneçam uniformes. Certifique-se de que o rosto na imagem está no meio, caso contrário, o rosto será cortado. Finalmente, converta todas essas imagens em numpy array para obter um valor matemático para as imagens. Em seguida, use o classificador em cascata para detectar as faces nas imagens e armazenar o resultado em uma variável chamada faces.


Gery_Image = Image.open(path).convert("L") # convert the image to greysclae using Pillow

Crop_Image = Gery_Image.resize( (550,550) , Image.ANTIALIAS) #Crop the Grey Image to 550*550 (Make sure your face is in the center in all image)

Final_Image = np.array(Crop_Image, "uint8")

faces = face_cascade.detectMultiScale(Final_Image, scaleFactor=1.5, minNeighbors=5) #Detect The face in all sample image


Assim que o rosto for detectado, vamos cortar essa área e considerá-la como nossa região de interesse (ROI). A região ROI será usada para treinar o reconhecedor de rosto. Temos que anexar cada face ROI dentro de uma variável chamada x_train. Em seguida, fornecemos esses valores de ROI junto com o valor de ID facial para o reconhecedor, que nos fornecerá os dados de treinamento. Os dados assim obtidos serão salvos.


for (x,y,w,h) in faces:

roi = Final_Image[y:y+h, x:x+w] #crop the Region of Interest (ROI)

x_train.append(roi)

y_ID.append(Face_ID)


recognizer.train(x_train, np.array(y_ID)) #Create a Matrix of Training data

recognizer.save("face-trainner.yml") #Save the matrix as YML file


Ao compilar este programa, você descobrirá que o arquivo face-trainner.yml é sempre atualizado. Portanto, certifique-se de compilar este programa sempre que fizer qualquer alteração nas fotos no diretório Face_Images. Quando compilado, você obterá o ID do rosto, o nome do caminho, o nome da pessoa e a matriz numpy impressa como mostrado abaixo para fins de depuração.


Programa de reconhecimento facial



Agora que temos nossos dados treinados prontos, podemos usá-los para reconhecer rostos agora. No programa Face Recognizer, obteremos um feed de vídeo ao vivo de uma webcam USB e depois o converteremos em imagem. Em seguida, temos que usar nossa técnica de detecção de rosto para detectar os rostos nessas fotos e, em seguida, compará-lo com todos os IDs de rosto que criamos anteriormente. Se encontrarmos uma correspondência, podemos encaixar o rosto e escrever o nome da pessoa que foi reconhecida. O programa completo é fornecido novamente no final, a explicação para o mesmo é a seguinte.

O programa compartilha muitas semelhanças com o programa treinador, então importe os mesmos módulos que usamos anteriormente e também use o classificador, pois precisamos realizar a detecção de rosto novamente.



import cv2 #For Image processing

import numpy as np #For converting Images to Numerical array

import os #To handle directories

from PIL import Image #Pillow lib for handling images


face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

recognizer = cv2.createLBPHFaceRecognizer()


Em seguida, nos rótulos das variáveis, você deve escrever o nome das pessoas que foram mencionadas na pasta. Certifique-se de seguir a mesma ordem. No meu caso, é meu nome “Aswinth” e “Elon”.


labels = ["Aswinth", "Elon Musk"]



Em seguida, temos que carregar o arquivo face-trainner.yml em nosso programa, pois teremos que usar os dados desse arquivo para reconhecer faces.


recognizer.load("face-trainner.yml")



O feed de vídeo é obtido da webcam USB. Se você tiver mais de uma câmera conectada, substitua 0 por 1 para acessar a câmera secundária.


cap = cv2.VideoCapture(0) #Get vidoe feed from the Camera



Em seguida, dividimos o vídeo em quadros (Imagens), convertemos em tons de cinza e detectamos os rostos na imagem. Assim que os rostos forem detectados, temos que cortar essa área como fizemos anteriormente e salvá-la separadamente como roi_gray.


ret, img = cap.read() # Break video into frames

gray  = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #convert Video frame to Greyscale

faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=5) #Recog. faces

for (x, y, w, h) in faces:

roi_gray = gray[y:y+h, x:x+w] #Convert Face to greyscale



id_, conf = recognizer.predict(roi_gray) #recognize the Face


A variável conf nos diz o quão confiante o software está reconhecendo o rosto. Se o nível de confiança for maior que 80, obtemos o nome da pessoa usando o número de identificação usando a linha de código abaixo. Em seguida, desenhe uma caixa ao redor do rosto da pessoa e escreva o nome da pessoa no topo da caixa.


if conf>=80:

        font = cv2.FONT_HERSHEY_SIMPLEX #Font style for the name

        name = labels[id_] #Get the name from the List using ID number

        cv2.putText(img, name, (x,y), font, 1, (0,0,255), 2)

cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)


Finalmente, temos que exibir o feed de vídeo que acabamos de analisar e, em seguida, interromper o feed quando uma tecla de espera (aqui q) for pressionada.


cv2.imshow('Preview',img) #Display the Video

if cv2.waitKey(20) & 0xFF == ord('q'):

   break


Certifique-se de que o Pi esteja conectado a um monitor por meio de HDMI quando este programa for executado. Execute o programa e você encontrará uma janela aparecendo com a visualização do nome e seu feed de vídeo nele. Se um rosto for reconhecido no feed de vídeo, você encontrará uma caixa ao redor dele e se o seu programa puder reconhecer o rosto, ele também exibirá o nome da pessoa. Treinamos nosso programa para reconhecer a mim e a Elon Musk e você pode ver os dois sendo reconhecidos na foto abaixo.

Uma vez que o problema perceptível é que a taxa de quadros é muito lenta. Estou obtendo um quadro a cada 3 segundos. O mesmo programa quando executado no meu laptop (com pequenas alterações) me deu resultados muito impressionantes. Também não espere que seja muito preciso, os dados do nosso treinador são muito simples, então o programa não será muito confiável. Você pode verificar como usar o aprendizado profundo para treinar seu conjunto de dados para melhorar a precisão. Existem maneiras de aumentar o FPS (quadro por segundo), mas vamos deixar isso para outro tutorial.

Espero que você tenha entendido o artigo e conseguido implementar seu próprio sistema de reconhecimento de rosto.


ENTRE EM CONTATO COM A LOJAMUNDI.

Assine nossa Newsletter! É gratuito!

Cadastre seu nome e email para receber novidades e materiais gratuitos da Lojamundi.