Reconhecimento facial com OpenCV
A complexidade das máquinas aumentou ao longo dos anos e os computadores não são uma exceção. Os computadores ajudaram a humanidade a resolver muitos problemas e realizar muitas tarefas difíceis. Já se foi o tempo em que tudo que os computadores faziam eram operações aritméticas simples, os computadores agora conduzem o mundo.
Os computadores se tornaram tão complexos que estão sendo treinados para pensar como humanos.
sim!
Faremos algo dessa natureza neste artigo. Como humanos, reconhecer os rostos de outras pessoas é uma tarefa simples e apesar das habilidades dos computadores de hoje não é tão fácil para o computador, então temos que treiná-lo para ser capaz de fazer o mesmo.
Muitos artigos que você veria por aí chegam a parar na simples detecção de rosto, mas neste artigo cobrem não apenas a detecção de rosto, mas também o reconhecimento de rosto.
Isso significa que se duas fotos minhas fossem apresentadas ao computador, ele não apenas reconheceria que parte da foto é o meu rosto, mas também reconheceria que eu sou a única em ambas as fotos.
Para começar, teríamos que primeiro instalar o opencv em nossas máquinas, o que só pode ser feito se você tiver o Python instalado. A instalação do Python não é o objetivo deste artigo, então, se ainda não o tiver em sua máquina, você pode instalar o Python a partir do site do Python.
Para instalar o Open CV, podemos fazer isso usando o comando pip.
pip install opencv-pythonTambém faremos uso do pacote numpy neste artigo, que deve ser instalado junto com o OpenCV usando o comando acima.
Se o numpy não foi instalado, você pode fazer isso facilmente usando o comando abaixo:
pip install numpyPara confirmar se o OpenCV está instalado, ao ativar o ambiente interativo do Python, tente importá-lo usando:
import cv2Se não obtiver um erro, você pode prosseguir.
Para realizar o reconhecimento facial, estaríamos escrevendo três scripts. Um para criar um conjunto de dados de imagens, outro para treinar essas imagens e o último para reconhecer os rostos com base nos resultados do treinamento pelo qual o computador passa.
Estaríamos precisando do Haar Cascade fornecido pela Open CV. Este arquivo pode ser obtido no diretório opencv que é cv2 / data / haarcascade_frontalface_default.xml na minha máquina deve ser o mesmo na sua máquina também. Copie o arquivo para a pasta onde você deseja fazer o reconhecimento facial.
Agora vamos entrar no meio das coisas.
Tentaríamos fazer com que nossa webcam conseguisse as fotos necessárias para o conjunto de dados.
vid_cam = cv2.VideoCapture (0)
face_detector = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml ')
face_id = 1
contagem = 0
while (vid_cam.está aberto()):
ret, imagem_frame = vid_cam.leitura()
cinza = cv2.cvtColor (imagem_frame, cv2.COLOR_BGR2GRAY)
faces = face_detector.detectMultiScale (cinza, 1.3, 5)
para (x, y, w, h) nas faces:
cv2.retângulo (imagem_frame, (x, y), (x + w, y + h), (255,0,0), 2)
contagem + = 1
cv2.imwrite ("conjunto de dados / Usuário."+ str (face_id) + '.'+ str (contagem) + ".jpg ", cinza [y: y + h, x: x + w])
cv2.imshow ('frame', image_frame)
se cv2.waitKey (100) & 0xFF == ord ('q'):
pausa
contagem elif> 100:
pausa
vid_cam.liberação()
cv2.destroyAllWindows ()
Então, para explicar o que cada linha de código faz:
import cv2Aqui está o comando que diz ao python para incluir uma biblioteca externa a ser usada neste código, neste caso é Open CV.
vid_cam = cv2.VideoCapture (0)Este código chama a biblioteca Open CV importada para começar a capturar e a webcam é iniciada neste ponto. Se o Open CV não suportar sua webcam, o código falhará aqui.
face_detector = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml ')Para que possamos realizar a detecção de imagens, este código é necessário. O CV aberto usa o 'haarcascade_frontalface_default.xml 'para classificação Cascade. O objeto resultante é então armazenado na variável face_detector.
face_id = 1Aqui está um caso de configuração do número de id do rosto, então o primeiro rosto recebe um id de 1.
contagem = 0Vamos tirar algumas imagens, pois o Open CV precisa treinar imagens para ser capaz de reconhecer rostos, a variável de contagem serve como uma contagem de imagens.
while (vid_cam.está aberto()):Isso permite que as seguintes operações prossigam, desde que a câmera de vídeo esteja aberta. O método isOpened () retorna True ou False.
ret, imagem_frame = vid_cam.leitura()Aqui, a vid_cam.read () olha para a captura de vídeo e então captura o quadro que está armazenado na variável image_frame, se a operação for bem sucedida o booleano True é retornado e armazenado na variável ret
cinza = cv2.cvtColor (imagem_frame, cv2.COLOR_BGR2GRAY)O método cvtColor () é usado para converter o quadro da imagem no tipo de cor desejado. Neste caso, nós o convertemos em tons de cinza.
faces = face_detector.detectMultiScale (cinza, 1.3, 5)Isso verifica os quadros de tamanhos diferentes e tenta ajustá-los em escala, isso é aplicado na variável à qual a Cascata de Haar foi aplicada.
para (x, y, w, h) nas faces:Aqui, fazemos um loop pelas faces e suas dimensões, onde xey representam as coordenadas ew e h representam largura e altura, respectivamente.
cv2.retângulo (imagem_frame, (x, y), (x + w, y + h), (255,0,0), 2)Lembre-se que ainda estamos trabalhando com a câmera de vídeo, a câmera de vídeo então corta a parte necessária da imagem de acordo com as dimensões acima.
contagem + = 1Isso é feito imediatamente, a variável de contagem que funciona como um contador, em seguida, aumenta.
cv2.imwrite ("conjunto de dados / Usuário."+ str (face_id) + '.'+ str (contagem) + ".jpg ", cinza [y: y + h, x: x + w])A imagem recortada é salva com o nome de usuário (face_id).(contar).jpg e colocado em uma pasta chamada dataset.
cv2.imshow ('frame', image_frame)Após salvar, este código garante que o quadro de vídeo da imagem seja exibido com um retângulo no rosto do indivíduo após a detecção de rosto.
se cv2.waitKey (100) & 0xFF == ord ('q'):pausa
Após cada foto, o usuário pode parar o programa de tirar mais fotos, o que pode ser feito pressionando 'q' no teclado por pelo menos 100ms.
contagem elif> 100:pausa
O que esse código faz é parar o vídeo de funcionar no momento em que 100 fotos foram tiradas, independentemente se o usuário deseja tirar mais ou não.
vid_cam.liberação()Aqui, a webcam está fechada e não apenas impedida de tirar fotos.
cv2.destroyAllWindows ()Então, todas as janelas que o OpenCV abriu foram destruídas e o código é executado até a conclusão.
Agora que terminamos com isso, podemos treinar o conjunto de dados da imagem:
importar cv2, osimportar numpy como np
da imagem de importação PIL
reconhecedor = cv2.Rosto.createLBPHFaceRecognizer ()
detector = cv2.CascadeClassifier ("haarcascade_frontalface_default.xml ");
def getImagesAndLabels (caminho):
imagePaths = [os.caminho.junte (caminho, f) para f em os.listdir (caminho)]
faceSamples = []
ids = []
para imagePath em imagePaths:
PIL_img = Imagem.abrir (imagePath).converter ('L')
img_numpy = np.matriz (PIL_img, 'uint8')
id = int (os.caminho.dividir (imagePath) [- 1].dividir(".") [1])
faces = detector.detectMultiScale (img_numpy)
para (x, y, w, h) nas faces:
faceSamples.anexar (img_numpy [y: y + h, x: x + w])
ids.anexar (id)
return faceSamples, ids
faces, ids = getImagesAndLabels ('dataset')
Reconhecedor.trem (rostos, np.array (ids))
Reconhecedor.salvar ('treinador / treinador.yml ')
Vamos prosseguir e explicar este código também:
importar cv2, osAssim como o outro código, aqui estamos importando OpenCV e OS que precisaríamos para o caminho do arquivo.
importar numpy como npTambém estamos importando a biblioteca numpy que seria usada para o cálculo da matriz (uma matriz é apenas um arranjo de matrizes).
da imagem de importação PILEstamos importando a biblioteca de imagens Python e, a partir dela, também obtemos a biblioteca de imagens deste pacote.
reconhecedor = cv2.Rosto.createLBPHFaceRecognizer ()O que isso faz é aplicar o método createLBPHFaceRecognizer () ao cv2.objeto de rosto, isso ajudaria a tornar o reconhecimento de rostos mais fácil, pois não temos que criar nosso próprio conjunto de algoritmos.
detector = cv2.CascadeClassifier ("haarcascade_frontalface_default.xml ");Se você tem seguido o tutorial, já deve ter se deparado com isso antes. Ajuda na detecção de rosto usando o “haarcascade_frontalface_default.xml ”para a Classificação Cascade.
def getImagesAndLabels (caminho):Agora, estamos prestes a começar o treinamento de imagem propriamente dito, então criamos uma função.
imagePaths = [os.caminho.junte (caminho, f) para f em os.listdir (caminho)]Este código verifica o diretório atual do arquivo e verifica os arquivos de imagem, em seguida, adiciona-os a esta lista.
faceSamples = []Isso inicializa uma lista de amostras, está vazio neste ponto, mas rostos seriam adicionados conforme o código é executado.
ids = []Inicializa uma lista de ids, que está inicialmente vazia.
para imagePath em imagePaths:Lembre-se do código que verificou os arquivos de imagem no diretório? sim? Agora, vamos percorrer cada um desses arquivos e realizar operações neles.
PIL_img = Imagem.abrir (imagePath).converter ('L')Agora, a primeira coisa que fazemos com a imagem é convertê-la em tons de cinza, e este código faz isso.
img_numpy = np.matriz (PIL_img, 'uint8')A imagem em escala de cinza é apenas uma série de números em um só lugar, então criamos um array numpy a partir deles e o atribuímos a uma variável.
id = int (os.caminho.dividir (imagePath) [- 1].dividir(".") [1])Se você se lembrar do arquivo que obtém as imagens, deve se lembrar de que nomeamos os arquivos como User (face_id).contar.jpg. Então, aqui estamos dividindo os nomes com o “.”E então extraímos o face_id e atribuímos a uma variável aqui. Precisaríamos da id para reconhecimento.
faces = detector.detectMultiScale (img_numpy)A partir da matriz numpy, o método detectMultiScale () tentará detectar os rostos a partir do padrão que encontrar na matriz numpy. Em seguida, ele atribui os valores na variável faces.
para (x, y, w, h) nas faces:Aqui, estamos percorrendo os valores atribuídos à variável. Os valores aqui são as coordenadas xey que poderíamos tomar como origem, e então w e h representando largura e altura respectivamente.
faceSamples.anexar (img_numpy [y: y + h, x: x + w])Anteriormente, criamos uma lista de amostras de rosto, mas estava vazia. Aqui podemos adicionar faces a essa lista, e estamos adicionando y ah para obter os dois valores das coordenadas y e o mesmo é feito para x.
ids.anexar (id)Agora temos um rosto na lista de amostra de rosto, então pegamos seu id e o anexamos à lista de ids também.
return faceSamples, idsDepois de tudo, retornamos a lista de amostras de rosto e a lista de ids.
faces, ids = getImagesAndLabels ('dataset')Lembre-se de que getImagesAndLabels () é apenas uma função. Então, podemos chamar a função aqui, e os valores de retorno são salvos nas variáveis faces e ids.
Reconhecedor.trem (rostos, np.array (ids))Aqui é onde o verdadeiro treinamento acontece. Aplicamos o método createLBPHFaceRecognizer () algum tempo antes e atribuímos a uma variável de reconhecedor. É hora de treinar!
Reconhecedor.salvar ('treinador / treinador.yml ')Após o treinamento, podemos salvar os resultados do treinamento.
Depois de executar o código, ele cria um arquivo chamado trainer.yml que seria então usado pelo código de reconhecimento de rosto.
Aqui está o código de reconhecimento facial:
import cv2importar numpy como np
reconhecedor = cv2.Rosto.createLBPHFaceRecognizer ()
Reconhecedor.load ('treinador / treinador.yml ')
cascadePath = "haarcascade_frontalface_default.xml "
faceCascade = cv2.CascadeClassifier (cascadePath)
font = cv2.FONT_HERSHEY_SIMPLEX
cam = cv2.VideoCapture (0)
enquanto verdadeiro:
ret, im = cam.leitura()
cinza = cv2.cvtColor (im, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale (cinza, 1.2,5)
para (x, y, w, h) nas faces:
cv2.retângulo (im, (x-20, y-20), (x + w + 20, y + h + 20), (0,255,0), 4)
Id = reconhecedor.prever (cinza [y: y + h, x: x + w])
if (Id == 1):
Id = "Nazmi"
senão:
Id = "Desconhecido"
cv2.retângulo (im, (x-22, y-90), (x + w + 22, y-22), (0,255,0), -1)
cv2.putText (im, str (Id), (x, y-40), fonte, 2, (255,255,255), 3)
cv2.imshow ('im', im)
se cv2.waitKey (10) & 0xFF == ord ('q'):
pausa
cam.liberação()
cv2.destroyAllWindows ()
Se você tem seguido o artigo desde o início, já fizemos isso antes. Se você não fez por favor.
Reconhecedor.load ('treinador / treinador.yml ')Lembre-se de que treinamos o reconhecedor e salvamos um arquivo? sim? Estamos carregando esse arquivo agora.
cascadePath = "haarcascade_frontalface_default.xml "Estaríamos trabalhando com o arquivo haarcascade, e aqui atribuímos o nome do arquivo a uma variável.
# Criar classificador a partir do modelo pré-construídofaceCascade = cv2.CascadeClassifier (cascadePath)
Aqui podemos realizar a classificação Cascade no arquivo haarcascade.
font = cv2.FONT_HERSHEY_SIMPLEXNós definimos o tipo de fonte que seria usado quando o código reconhecer o rosto em uma imagem e exibir o nome.
cam = cv2.VideoCapture (0)Já estivemos aqui antes, mas desta vez é hora de reconhecer os rostos. Se você não sabe o que este código faz, ele inicia a webcam.
enquanto verdadeiro:ret, im = cam.leitura()
cinza = cv2.cvtColor (im, cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale (cinza, 1.2,5)
para (x, y, w, h) nas faces:
Tudo isso já foi feito antes, por favor, verifique o código que foi usado para salvar as imagens se você não sabe o que o código faz.
cv2.retângulo (im, (x-20, y-20), (x + w + 20, y + h + 20), (0,255,0), 4)Isso ajuda a webcam a detectar onde estão os rostos e colocar um retângulo para indicar um rosto.
Id = reconhecedor.prever (cinza [y: y + h, x: x + w])Nós já carregamos o arquivo de trem no reconhecedor, então agora ele é capaz de reconhecer o rosto.
if (Id == 1):Id = "Eu"
senão:
Id = "Desconhecido"
Depois de tentar reconhecer que cara é, ele verifica o id e vê se ele existe. Aqui, o valor do Id seria o nome de quem possuía esse id quando o conjunto de dados da imagem estava sendo criado.
cv2.retângulo (im, (x-22, y-90), (x + w + 22, y-22), (0,255,0), -1)cv2.putText (im, str (Id), (x, y-40), fonte, 2, (255,255,255), 3)
O código depois de encontrar o dono do Id, desenha um retângulo ao redor do rosto e coloca o nome do dono do rosto. Rosto reconhecido!
cv2.imshow ('im', im)Aqui, o quadro de vídeo é exibido com o retângulo delimitado.
se cv2.waitKey (10) & 0xFF == ord ('q'):pausa
cam.liberação()
cv2.destroyAllWindows ()
Então, quando terminar, você pode parar o programa pressionando a tecla 'q', e ele para a webcam e fecha-a.
Aí está, sua webcam agora pode reconhecer rostos e você pode usá-la sempre que desejar. Além de usar a webcam, você também pode carregar uma imagem, no entanto, isso requer algumas outras etapas além das realizadas neste artigo.
Você pode encontrar o código-fonte usado em seu repositório github. Também envie um tweet para nós se você tiver comentários ou quiser discutir @linuxhint