Taula de continguts:

Reconeixement facial en temps real: un projecte d'extrem a extrem: 8 passos (amb imatges)
Reconeixement facial en temps real: un projecte d'extrem a extrem: 8 passos (amb imatges)

Vídeo: Reconeixement facial en temps real: un projecte d'extrem a extrem: 8 passos (amb imatges)

Vídeo: Reconeixement facial en temps real: un projecte d'extrem a extrem: 8 passos (amb imatges)
Vídeo: Дневник хранящий жуткие тайны. Переход. Джеральд Даррелл. Мистика. Ужасы 2024, De novembre
Anonim
Reconeixement facial en temps real: un projecte de punta a punta
Reconeixement facial en temps real: un projecte de punta a punta

En el meu darrer tutorial que explorava OpenCV, vam aprendre el seguiment automàtic d’objectes de visió. Ara utilitzarem la nostra PiCam per reconèixer les cares en temps real, com podeu veure a continuació:

Imatge
Imatge

Aquest projecte es va fer amb aquesta fantàstica "Open Source Computer Vision Library", l'OpenCV. En aquest tutorial, ens centrarem en Raspberry Pi (per tant, Raspbian com a SO) i Python, però també he provat el codi al meu Mac i també funciona bé. OpenCV va ser dissenyat per a eficiència computacional i amb un enfocament fort en aplicacions en temps real. Per tant, és perfecte per al reconeixement facial en temps real mitjançant una càmera.

Per crear un projecte complet sobre reconeixement facial, hem de treballar en 3 fases ben diferenciades:

  1. Detecció de cares i recollida de dades
  2. Entrena el reconeixedor
  3. Reconeixement facial

El diagrama de blocs següent reprèn aquestes fases:

Imatge
Imatge

Pas 1: BoM: llista de materials

Parts principals:

  1. Raspberry Pi V3: 32,00 dòlars EUA
  2. Sensor de 5 megapíxels 1080p OV5647 Mòdul de vídeo de mini càmera: 13,00 dòlars EUA

Pas 2: Instal·lació del paquet OpenCV 3

Instal·lació del paquet OpenCV 3
Instal·lació del paquet OpenCV 3

Estic fent servir un Raspberry Pi V3 actualitzat a l’última versió de Raspbian (Stretch), de manera que la millor manera d’instal·lar OpenCV és seguir l’excel·lent tutorial desenvolupat per Adrian Rosebrock: Raspbian Stretch: Instal·leu OpenCV 3 + Python al vostre Raspberry Pi.

He provat diverses guies diferents per instal·lar OpenCV al meu Pi. El tutorial d’Adrià és el millor. Us aconsello que feu el mateix, seguint la seva pauta pas a pas.

Un cop hàgiu acabat el tutorial de l’Adrian, hauríeu de tenir un entorn virtual OpenCV a punt per executar els nostres experiments al vostre Pi.

Anem al nostre entorn virtual i confirmem que OpenCV 3 està instal·lat correctament.

Adrian recomana executar l'ordre "font" cada vegada que obriu un terminal nou per assegurar-vos que les variables del sistema s'han configurat correctament.

font ~ /.perfil

A continuació, entrem al nostre entorn virtual:

workon cv

Si veieu el text (cv) anterior a la vostra sol·licitud, esteu a l’entorn virtual cv:

(cv) pi @ raspberry: ~ $Adrian crida l'atenció que l'entorn virtual cv Python és completament independent i segrestat de la versió predeterminada de Python inclosa a la descàrrega de Raspbian Stretch. Per tant, els paquets Python del directori global de paquets lloc no estaran disponibles per a l'entorn virtual cv. De la mateixa manera, els paquets de Python instal·lats als paquets de lloc de CV no estaran disponibles per a la instal·lació global de Python

Ara, introduïu el vostre intèrpret de Python:

pitó

i confirmeu que esteu executant la versió 3.5 (o superior)

Dins de l'intèrpret (apareixerà el ">>>"), importeu la biblioteca OpenCV:

importar cv2

Si no apareixen missatges d'error, l'OpenCV està instal·lat correctament AL VOSTRE ENTORN VIRTUAL DE PITÓ.

També podeu consultar la versió OpenCV instal·lada:

cv2._ versió_

Ha d'aparèixer el 3.3.0 (o una versió superior que es pugui llançar en el futur). La Terminal PrintScreen anterior mostra els passos anteriors.

Pas 3: proveu la càmera

Prova de la càmera
Prova de la càmera

Un cop tingueu OpenCV instal·lat al vostre RPi, provem per confirmar que la càmera funciona correctament.

Suposo que ja teniu instal·lada una PiCam al vostre Raspberry Pi.

Introduïu el codi Python següent al vostre IDE:

importa numpy com a np

import cv2 cap = cv2. VideoCapture (0) cap.set (3, 640) # set Amplada cap.set (4, 480) # set Altura mentre que (True): ret, frame = cap.read () frame = cv2. flip (frame, -1) # Flip camera verticalment gris = cv2.cvtColor (frame, cv2. COLOR_BGR2GRAY) cv2.imshow ('frame', frame) cv2.imshow ('gray', gris) k = cv2.waitKey (30) & 0xff si k == 27: # premeu 'ESC' per sortir del break cap.release () cv2.destroyAllWindows ()

El codi anterior capturarà el flux de vídeo que generarà la vostra PiCam, mostrant-los tots dos, en color BGR i en mode gris.

Tingueu en compte que he girat la càmera verticalment pel seu muntatge. Si no és el vostre cas, comenteu o suprimiu la línia d'ordres "capgirar".

També podeu descarregar el codi del meu GitHub: simpleCamTest.py

Per executar, introduïu l'ordre:

python simpleCamTest.py

Per acabar el programa, heu de prémer la tecla [ESC] del teclat.

Feu clic amb el ratolí a la finestra del vídeo abans de prémer [ESC]

La imatge superior mostra el resultat.

Alguns fabricants han trobat problemes en intentar obrir la càmera (missatges d'error "No s'ha pogut afirmar"). Això podria passar si la càmera no estava habilitada durant la instal·lació d'OpenCv i, per tant, els controladors de càmera no s'instal·laven correctament. Per corregir, utilitzeu l'ordre:

sudo modprobe bcm2835-v4l2

També podeu afegir bcm2835-v4l2 a l'última línia del fitxer / etc / modules perquè el controlador es carregui a l'arrencada.

Per obtenir més informació sobre OpenCV, podeu seguir el tutorial: loading -video-python-opencv-tutorial

Pas 4: detecció de cares

Detecció de cares
Detecció de cares
Detecció de cares
Detecció de cares

La tasca més bàsica del reconeixement facial és, per descomptat, "Detecció de cares". Abans de res, heu de "capturar" una cara (fase 1) per reconèixer-la, en comparació amb una cara nova capturada en un futur (fase 3).

La forma més habitual de detectar una cara (o qualsevol objecte) és mitjançant el "classificador de cascades Haar"

La detecció d’objectes mitjançant classificadors en cascada basats en funcions de Haar és un mètode efectiu de detecció d’objectes proposat per Paul Viola i Michael Jones en el seu article, “Detecció ràpida d’objectes mitjançant una cascada augmentada de funcions simples” el 2001. Es tracta d’un enfocament basat en l’aprenentatge automàtic La funció en cascada s'entren a partir d'un munt d'imatges positives i negatives. Després s’utilitza per detectar objectes en altres imatges.

Aquí treballarem amb la detecció de cares. Inicialment, l'algorisme necessita moltes imatges positives (imatges de cares) i imatges negatives (imatges sense cares) per entrenar el classificador. Després, n’hem d’extreure funcions. La bona notícia és que OpenCV inclou un entrenador i un detector. Si voleu entrenar el vostre propi classificador per a qualsevol objecte com cotxe, avions, etc., podeu utilitzar OpenCV per crear-ne un. Aquí es detallen tots els detalls: Formació classificadora en cascada.

Si no voleu crear el vostre propi classificador, OpenCV ja conté molts classificadors pre-entrenats per a cara, ulls, somriure, etc. Aquests fitxers XML es poden descarregar des del directori haarcascades.

Prou teoria, creem un detector de cares amb OpenCV!

Descarregueu el fitxer: faceDetection.py des del meu GitHub.

importa numpy com a np

import cv2 faceCascade = cv2. CascadeClassifier ('Cascades / haarcascade_frontalface_default.xml') cap = cv2. VideoCapture (0) cap.set (3, 640) # set Amplada cap.set (4, 480) # set Altura mentre que True: ret, img = cap.read () img = cv2.flip (img, -1) gris = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale (gris, scaleFactor = 1.2, minNeighbors = 5, minSize = (20, 20)) per a (x, y, w, h) en cares: cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gris [y: y + h, x: x + w] roi_color = img [y: y + h, x: x + w] cv2.imshow ('vídeo', img) k = cv2.waitKey (30) & 0xff si k == 27: # premeu 'ESC' per sortir del break cap.release () cv2.destroyAllWindows ()

Ho creieu o no, les línies de codi anteriors són tot el que necessiteu per detectar una cara, mitjançant Python i OpenCV.

Quan compareu amb l’últim codi utilitzat per provar la càmera, us adonareu que s’hi van afegir poques parts. Tingueu en compte la línia següent:

faceCascade = cv2. CascadeClassifier ('Cascades / haarcascade_frontalface_default.xml')

Aquesta és la línia que carrega el "classificador" (que ha d'estar en un directori anomenat "Cascades /", al directori del projecte).

A continuació, configurarem la càmera i, dins del bucle, carregarem el nostre vídeo d’entrada en mode d’escala de grisos (el mateix que vam veure abans).

Ara hem de trucar a la nostra funció classificadora, passant-li uns paràmetres molt importants, com ara el factor d’escala, el nombre de veïns i la mida mínima de la cara detectada.

faces = faceCascade.detectMultiScale (gris, escalaFactor = 1,2, mínim Veïns = 5, mida mínima = (20, 20))

On,

  • el gris és la imatge en escala de grisos d’entrada.
  • scaleFactor és el paràmetre que especifica quant es redueix la mida de la imatge a cada escala d’imatges. S’utilitza per crear la piràmide d’escales.
  • minNeighbors és un paràmetre que especifica quants veïns hauria de tenir cada rectangle candidat per conservar-lo. Un nombre més elevat dóna falsos positius.
  • minSize és la mida mínima del rectangle per considerar-se una cara.

La funció detectarà les cares de la imatge. A continuació, hem de "marcar" les cares de la imatge, utilitzant, per exemple, un rectangle blau. Això es fa amb aquesta part del codi:

per a (x, y, w, h) en cares:

cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gris [y: y + h, x: x + w] roi_color = img [y: y + h, x: x + w]

Si es troben cares, retorna les posicions de les cares detectades com un rectangle amb la cantonada esquerra cap amunt (x, y) i amb "w" com a Amplada i "h" com a Alçada ==> (x, y, w, h). Consulteu la imatge anterior.

Un cop obtinguem aquestes ubicacions, podem crear un "ROI" (rectangle dibuixat) per a la cara i presentar el resultat amb la funció imshow ().

Executeu l'script Python anterior al vostre entorn Python mitjançant el terminal Rpi:

python faceDetection.py

El resultat:

Imatge
Imatge

També podeu incloure classificadors per a "detecció d'ulls" o fins i tot "detecció de somriures". En aquests casos, inclourà la funció classificador i el dibuix de rectangle dins del bucle de la cara, perquè no tindria sentit detectar un ull o un somriure fora d’una cara.

Tingueu en compte que en un Pi, tenir diversos classificadors al mateix codi alentirà el processament, una vegada que aquest mètode de detecció (HaarCascades) utilitzi una gran quantitat de potència computacional. En un escriptori, és més fàcil executar-lo.

Al meu GitHub hi trobareu altres exemples:

faceEyeDetection.py

faceSmileDetection.py

faceSmileEyeDetection.py

I a la imatge anterior, podeu veure el resultat.

També podeu seguir el tutorial següent per entendre millor la detecció de cares:

Haar Cascade Detecció d'objectes Tutorial OpenCV Python de cara i ulls

Pas 5: recollida de dades

Recollida de dades
Recollida de dades
Recollida de dades
Recollida de dades

En primer lloc, he d’agrair a Ramiz Raja el seu gran treball en el reconeixement de cares a les fotos:

RECONEIXEMENT DE CARES AMB OPENCV I PITÓ: UNA GUIA PER AL PRINCIPIANT

i també Anirban Kar, que va desenvolupar un tutorial molt complet amb vídeo:

RECONEIXEMENT CARA - 3 parts

Us recomano que feu una ullada a tots dos tutorials.

Dit això, comencem la primera fase del nostre projecte. El que farem aquí és a partir del darrer pas (Detecció de cares), simplement crearem un conjunt de dades, on emmagatzemarem per a cada identificador, un grup de fotos en gris amb la porció que es va utilitzar per a la detecció de cares.

En primer lloc, creeu un directori on desenvolupeu el vostre projecte, per exemple, FacialRecognitionProject:

mkdir FacialRecognitionProject

En aquest directori, a més dels 3 scripts python que crearem per al nostre projecte, hem d’haver desat el Classificador Facial. El podeu descarregar des del meu GitHub: haarcascade_frontalface_default.xml

A continuació, creeu un subdirectori on desarem les mostres facials i anomenarem "conjunt de dades":

conjunt de dades mkdir

I descarregueu el codi del meu GitHub: 01_face_dataset.py

importar cv2

import os cam = cv2. VideoCapture (0) cam.set (3, 640) # set width video cam.set (4, 480) # set video height face_detector = cv2. CascadeClassifier ('haarcascade_frontalface_default.xml') # Per a cada persona, introduïu un identificador de cara numèrica face_id = input ('\ n introduïu l'identificador d'usuari final premeu ==>') imprimeix ("\ n [INFO] Inicialitzant la captura de cares. Mireu la càmera i espereu …") # Inicialitzeu el recompte de cares de mostreig individual = 0 mentre que (True): ret, img = cam.read () img = cv2.flip (img, -1) # flip imatge de vídeo verticalment gris = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) faces = face_detector.detectMultiScale (gris, 1,3, 5) per a (x, y, w, h) en cares: cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) count + = 1 # Deseu la imatge capturada a la carpeta de conjunts de dades cv2.imwrite ("dataset / User." + str (face_id) + '.' + str (count) + ".jpg", gris [y: y + h, x: x + w]) cv2.imshow ('image', img) k = cv2.waitKey (100) & 0xff # Premeu 'ESC' per sortir del vídeo si k == 27: interrupció del recompte elif> = 30: # Preneu una mostra de 30 cares i atureu el descans del vídeo de neteja d'impressió ("\ n [INFO] S'està sortint del programa i coses de neteja") cam.release () cv2.destroyAllWindows ()

El codi és molt similar al que hem vist per a la detecció de cares. El que vam afegir va ser una "ordre d'entrada" per capturar un identificador d'usuari, que hauria de ser un nombre enter (1, 2, 3, etc.)

face_id = input ('\ n introdueix l'identificador d'usuari final premeu ==>')

I per a cadascun dels marcs capturats, hauríem de desar-lo com a fitxer en un directori "conjunt de dades":

cv2.imwrite ("conjunt de dades / usuari." + str (face_id) + '.' + str (count) + ".jpg", gris [y: y + h, x: x + w])

Tingueu en compte que per desar el fitxer anterior, heu d'importar la biblioteca "os". El nom de cada fitxer seguirà l'estructura:

User.face_id.count.jpg

Per exemple, per a un usuari amb un Face_id = 1, el quart fitxer de mostra al conjunt de dades / directori serà com:

Usuari.1.4.jpg

tal com es mostra a la foto anterior del meu Pi. Al meu codi, capturo 30 mostres de cada identificador. Podeu canviar-lo a l'últim "elif". El nombre de mostres s’utilitza per trencar el bucle on es capturen les mostres de la cara.

Executeu l'script de Python i captureu alguns identificadors. Heu d'executar l'script cada vegada que vulgueu agregar un usuari nou (o canviar les fotos per una que ja existeix).

Pas 6: entrenador

Entrenador
Entrenador

En aquesta segona fase, hem de prendre totes les dades d'usuari del nostre conjunt de dades i "entrenar" l'OpenCV Recognizer. Això es fa directament mitjançant una funció OpenCV específica. El resultat serà un fitxer.yml que es desarà en un directori "entrenador /".

Comencem, doncs, a crear un subdirectori on emmagatzemarem les dades entrenades:

entrenador mkdir

Descarregueu del meu GitHub el segon script python: 02_face_training.py

importar cv2

import numpy as np from PIL import Image import os # Path for face image database path path = 'dataset' recognizer = cv2.face. LBPHFaceRecognizer_create () detector = cv2. CascadeClassifier ("haarcascade_frontalface_default.xml"); # funció per obtenir les imatges i etiquetar les dades def getImagesAndLabels (ruta): imagePaths = [os.path.join (path, f) per f a os.listdir (path)] faceSamples = ids = per imagePath a imagePaths: PIL_img = Image.open (imagePath).convert ('L') # converteix-lo a escala de grisos img_numpy = np.array (PIL_img, 'uint8') id = int (os.path.split (imagePath) [- 1]. split (".") [1]) faces = detector.detectMultiScale (img_numpy) for (x, y, w, h) in faces: faceSamples.append (img_numpy [y: y + h, x: x + w]) ids.append (id) return faceSamples, ids print ("\ n [INFO] Cares d'entrenament. Trigarà uns segons. Espereu …") cares, ids = getImagesAndLabels (path) recognizer.train (faces, np.array (ids)) # Deseu el model a trainer / trainer.yml recognizer.write ('trainer / trainer.yml') # recognizer.save () ha funcionat a Mac, però no a Pi # Imprimeix el nombre de cares entrenades i finalitza la impressió del programa ("\ n [INFO] {0} cares entrenades. Surt del programa".format (len (np.unique (ids))))

Confirmeu si teniu instal·lada la biblioteca PIL al vostre Rpi. Si no, executeu l'ordre següent a Terminal:

pip instal·lar coixí

Utilitzarem com a reconeixedor el reconeixedor facial LBPH (LOCAL BINARY PATTERNS HISTOGRAMS), inclòs al paquet OpenCV. Ho fem a la següent línia:

recognizer = cv2.face. LBPHFaceRecognizer_create ()

La funció "getImagesAndLabels (path)", farà totes les fotos del directori: "dataset /", retornant 2 matrius: "Ids" i "faces". Amb aquestes matrius com a entrada, "entrenarem el nostre reconeixedor":

recognizer.train (cares, identificadors)

Com a resultat, es desarà un fitxer anomenat "trainer.yml" al directori de l'entrenador que anteriorment hem creat.

Això és! Vaig incloure l'última declaració impresa on vaig mostrar per confirmar-me, el nombre de cares d'usuari que hem format.

Cada vegada que realitzeu la fase 1, també s’ha d’executar la fase 2

Pas 7: reconeixedor

Reconeixedor
Reconeixedor
Reconeixedor
Reconeixedor

Ara vam arribar a la fase final del nostre projecte. Aquí capturarem una cara nova a la càmera i, si aquesta persona ha tingut la cara captada i entrenada abans, el nostre reconeixedor farà una "predicció" que retorna el seu identificador i un índex, que mostrarà la confiança del reconeixedor amb aquesta coincidència.

Baixem l’escriptura Python de la tercera fase del meu GitHub: 03_face_recognition.py.

importar cv2

import numpy as np import os recognizer = cv2.face. LBPHFaceRecognizer_create () recognizer.read ('trainer / trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2. CascadeClassifier (cascadePath); font = cv2. FONT_HERSHEY_SIMPLEX #iniciate id counter id = 0 # noms relacionats amb identificadors: exemple ==> Marcelo: id = 1, etc names = ['Cap', 'Marcelo', 'Paula', 'Ilza', 'Z ',' W '] # Inicialitzeu i inicieu la captura de vídeo en temps real cam = cv2. VideoCapture (0) cam.set (3, 640) # set video widht cam.set (4, 480) # definiu l'alçada del vídeo # Definiu la mida mínima de la finestra que es reconegui com a cara minW = 0,1 * cam.get (3) minH = 0,1 * cam.get (4) mentre és True: ret, img = cam.read () img = cv2.flip (img, -1) # Invertir verticalment gris = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale (gris, scaleFactor = 1.2, minNeighbors = 5, minSize = (int (minW), int (minH)),) per (x, y, w, h) a les cares: cv2.rectangle (img, (x, y), (x + w, y + h), (0, 255, 0), 2) id, confiança = recognizer.predict (gris [y: y + h, x: x + w]) # Comproveu si la confiança és inferior a ells 100 ==> "0" és perfecte si (confiança <100): id = noms [id] confiança = "{0}% ".format (ronda (100 - confiança)) else: id =" desconegut "confiança =" {0}% ". format (ronda (100 - conf) idence)) cv2.putText (img, str (id), (x + 5, y-5), font, 1, (255, 255, 255), 2) cv2.putText (img, str (confiança), (x + 5, y + h-5), tipus de lletra, 1, (255, 255, 0), 1) cv2.imshow ("càmera", img) k = cv2.waitKey (10) i 0xff # Premeu "ESC" per sortir del vídeo si k == 27: break # Feu una mica d'impressió de neteja ("\ n [INFO] Surt del programa i coses de neteja") cam.release () cv2.destroyAllWindows ()

Incloem aquí una nova matriu, de manera que mostrarem "noms" en lloc d'identificadors numerats:

names = ['Cap', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W']

Així, per exemple: Marcelo farà l’usuari amb id = 1; Paula: id = 2, etc.

A continuació, detectarem una cara, igual que abans amb el classificador haasCascade. Si tenim una cara detectada, podem anomenar la funció més important del codi anterior:

id, confiança = recognizer.predict (porció gris de la cara)

El recognizer.predict (), prendrà com a paràmetre una porció capturada de la cara que s’analitzarà i retornarà el seu probable propietari, indicant el seu identificador i la quantitat de confiança que té el reconeixedor en relació amb aquesta coincidència.

Tingueu en compte que l'índex de confiança retornarà "zero" si es considera una coincidència perfecta

I, finalment, si el reconeixedor podria predir una cara, posem un text sobre la imatge amb la identificació probable i quant és la "probabilitat" en% que la coincidència sigui correcta ("probabilitat" = 100 - índex de confiança). Si no, es posa una etiqueta "desconegut" a la cara.

A sota d’un-g.webp

Imatge
Imatge

A la imatge anterior, mostro algunes proves fetes amb aquest projecte, on també he utilitzat fotos per verificar si el reconeixement funciona.

Pas 8: Conclusió

Conclusió
Conclusió

Com sempre, espero que aquest projecte pugui ajudar els altres a endinsar-se en l’apassionant món de l’electrònica.

Per obtenir més informació i el codi final, visiteu el meu dipòsit de GitHub: OpenCV-Face-Recognition

Per obtenir més projectes, visiteu el meu bloc: MJRoBot.org

A continuació, es fa un cop d'ull a un futur tutorial, on explorarem "la pista facial automàtica i altres mètodes per a la detecció de cares":

Imatge
Imatge

Saluts del sud del món!

Ens veiem a la meva propera instrucció!

Gràcies, Marcelo

Recomanat: