Cuprins:

Recunoașterea feței în timp real: un proiect end-to-end: 8 pași (cu imagini)
Recunoașterea feței în timp real: un proiect end-to-end: 8 pași (cu imagini)

Video: Recunoașterea feței în timp real: un proiect end-to-end: 8 pași (cu imagini)

Video: Recunoașterea feței în timp real: un proiect end-to-end: 8 pași (cu imagini)
Video: Ce înseamna semnul tau din nastere 2024, Iulie
Anonim
Recunoașterea feței în timp real: un proiect end-to-end
Recunoașterea feței în timp real: un proiect end-to-end

În ultimul meu tutorial explorând OpenCV, am învățat URMĂRIREA AUTOMATĂ A OBIECTELOR DE VIZIUNE. Acum vom folosi PiCam-ul nostru pentru a recunoaște fețele în timp real, după cum puteți vedea mai jos:

Imagine
Imagine

Acest proiect a fost realizat cu această fantastică "Open Source Computer Vision Library", OpenCV. Pe acest tutorial, ne vom concentra pe Raspberry Pi (deci, Raspbian ca SO) și Python, dar am testat și codul pe Mac-ul meu și funcționează bine. OpenCV a fost conceput pentru eficiența computațională și cu un accent puternic pe aplicații în timp real. Deci, este perfect pentru recunoașterea feței în timp real folosind o cameră foto.

Pentru a crea un proiect complet privind recunoașterea feței, trebuie să lucrăm pe 3 faze foarte distincte:

  1. Detectarea feței și colectarea datelor
  2. Antrenează-l pe recunoscător
  3. Recunoaștere facială

Diagrama bloc de mai jos reia acele faze:

Imagine
Imagine

Pasul 1: BoM - Lista materialelor

Părți principale:

  1. Raspberry Pi V3 - 32,00 USD
  2. 5 Megapixeli senzor 1080p OV5647 Modul video mini cameră - 13,00 USD

Pasul 2: Instalarea pachetului OpenCV 3

Instalarea pachetului OpenCV 3
Instalarea pachetului OpenCV 3

Folosesc un Raspberry Pi V3 actualizat la ultima versiune a Raspbian (Stretch), deci cel mai bun mod de a avea instalat OpenCV este să urmați excelentul tutorial dezvoltat de Adrian Rosebrock: Raspbian Stretch: Instalați OpenCV 3 + Python pe Raspberry Pi.

Am încercat mai multe ghiduri diferite pentru a instala OpenCV pe Pi. Tutorialul lui Adrian este cel mai bun. Vă sfătuiesc să faceți același lucru, urmând pas cu pas liniile directoare ale acestuia.

După ce ați terminat tutorialul lui Adrian, ar trebui să aveți un mediu virtual OpenCV pregătit pentru a rula experimentele noastre pe Pi.

Să mergem la mediul nostru virtual și să confirmăm că OpenCV 3 este instalat corect.

Adrian recomandă să executați comanda „sursă” de fiecare dată când deschideți un terminal nou pentru a vă asigura că variabilele de sistem au fost configurate corect.

sursa ~ /.profil

Apoi, să intrăm în mediul nostru virtual:

workon cv

Dacă vedeți textul (cv) care precede solicitarea dvs., atunci vă aflați în mediul virtual cv:

(cv) pi @ raspberry: ~ $Adrian atrage atenția că mediul virtual cv Python este complet independent și sechestrat de versiunea implicită Python inclusă în descărcarea Raspbian Stretch. Deci, orice pachet Python din directorul global site-pachete nu va fi disponibil mediului virtual cv. În mod similar, orice pachete Python instalate în site-pachete de cv nu vor fi disponibile pentru instalarea globală a Python

Acum, introduceți în interpretul dvs. Python:

piton

și confirmați că rulați versiunea 3.5 (sau mai mare)

În interiorul interpretului (va apărea „>>>”), importați biblioteca OpenCV:

import cv2

Dacă nu apar mesaje de eroare, OpenCV este instalat corect PE MEDIUL VIRTUAL PYTHON.

De asemenea, puteți verifica versiunea OpenCV instalată:

cv2._ versiunea_

3.3.0 ar trebui să apară (sau o versiune superioară care poate fi lansată în viitor). Terminalul PrintScreen de mai sus arată pașii anteriori.

Pasul 3: Testarea camerei foto

Testarea camerei foto
Testarea camerei foto

Odată ce ați instalat OpenCV în RPi, să testăm pentru a confirma că camera dvs. funcționează corect.

Presupun că aveți deja o PiCam instalată pe Raspberry Pi.

Introduceți codul Python de mai jos pe IDE:

import numpy ca np

import cv2 cap = cv2. VideoCapture (0) cap.set (3, 640) # set Width cap.set (4, 480) # set Height while (True): ret, frame = cap.read () frame = cv2. flip (cadru, -1) # Flip camera vertical gri = cv2.cvtColor (cadru, cv2. COLOR_BGR2GRAY) cv2.imshow („cadru”, cadru) cv2.imshow („gri”, gri) k = cv2.waitKey (30) & 0xff dacă k == 27: # apăsați „ESC” pentru a părăsi cap.release () cv2.destroyAllWindows ()

Codul de mai sus va captura fluxul video care va fi generat de PiCam, afișând ambele, în culori BGR și în modul Gri.

Rețineți că mi-am rotit camera pe verticală datorită modului în care este asamblat. Dacă nu este cazul dvs., comentați sau ștergeți linia de comandă „flip”.

Puteți descărca alternativ codul din GitHub: simpleCamTest.py

Pentru a executa, introduceți comanda:

python simpleCamTest.py

Pentru a termina programul, trebuie să apăsați tasta [ESC] de pe tastatură.

Faceți clic cu mouse-ul pe fereastra video, înainte de a apăsa [ESC]

Imaginea de mai sus arată rezultatul.

Unii producători au găsit probleme atunci când au încercat să deschidă camera (mesajele de eroare „Afirmare eșuată”). Acest lucru s-ar putea întâmpla dacă camera nu a fost activată în timpul instalării OpenCv și astfel driverele camerei nu s-au instalat corect. Pentru a corecta, utilizați comanda:

sudo modprobe bcm2835-v4l2

De asemenea, puteți adăuga bcm2835-v4l2 la ultima linie a fișierului / etc / modules, astfel încât driverul să se încarce la pornire.

Pentru a afla mai multe despre OpenCV, puteți urma tutorialul: încărcare -video-python-opencv-tutorial

Pasul 4: Detectarea feței

Detectare facială
Detectare facială
Detectare facială
Detectare facială

Sarcina cea mai de bază privind recunoașterea feței este, desigur, „Detectarea feței”. Înainte de orice, trebuie să „capturați” o față (Faza 1) pentru a o recunoaște, în comparație cu o față nouă capturată în viitor (Faza 3).

Cea mai obișnuită modalitate de a detecta o față (sau orice obiecte) este folosirea „clasificatorului Haar Cascade”

Detectarea obiectelor folosind clasificatori în cascadă bazate pe caracteristici Haar este o metodă eficientă de detectare a obiectelor propusă de Paul Viola și Michael Jones în lucrarea lor, „Rapid Object Detection using a Boosted Cascade of Simple Features” în 2001. Este o abordare bazată pe învățarea automată în care o funcția cascadă este antrenată dintr-o mulțime de imagini pozitive și negative. Este apoi folosit pentru a detecta obiecte din alte imagini.

Aici vom lucra cu detectarea feței. Inițial, algoritmul are nevoie de o mulțime de imagini pozitive (imagini ale fețelor) și imagini negative (imagini fără fețe) pentru a antrena clasificatorul. Apoi, trebuie să extragem caracteristici din acesta. Vestea bună este că OpenCV vine cu un antrenor, precum și cu un detector. Dacă doriți să vă antrenați propriul clasificator pentru orice obiect, cum ar fi mașina, avioanele etc., puteți utiliza OpenCV pentru a crea unul. Detaliile sale complete sunt prezentate aici: Instruire clasificator cascadă.

Dacă nu doriți să creați propriul dvs. clasificator, OpenCV conține deja multe clasificatoare pre-antrenate pentru față, ochi, zâmbet etc. Aceste fișiere XML pot fi descărcate din directorul haarcascades.

Destul de teorie, să creăm un detector de față cu OpenCV!

Descărcați fișierul: faceDetection.py din GitHub.

import numpy ca np

import cv2 faceCascade = cv2. CascadeClassifier ('Cascades / haarcascade_frontalface_default.xml') cap = cv2. VideoCapture (0) cap.set (3, 640) # set Lățime cap.set (4, 480) # set Înălțime în timp ce True: ret, img = cap.read () img = cv2.flip (img, -1) gri = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale (gri, scaleFactor = 1.2, minNeighbours = 5, minSize = (20, 20)) pentru (x, y, w, h) în fețe: cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) roi_gray = gri [y: y + h, x: x + w] roi_color = img [y: y + h, x: x + w] cv2.imshow („video”, img) k = cv2.waitKey (30) & 0xff dacă k == 27: # apăsați „ESC” pentru a părăsi pauza cap.release () cv2.destroyAllWindows ()

Credeți sau nu, câteva linii de cod de mai sus sunt tot ce aveți nevoie pentru a detecta o față, folosind Python și OpenCV.

Când comparați cu ultimul cod folosit pentru a testa camera, veți realiza că puține părți au fost adăugate la ea. Rețineți rândul de mai jos:

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

Aceasta este linia care încarcă „clasificatorul” (care trebuie să se afle într-un director numit „Cascade /”, sub directorul proiectului).

Apoi, ne vom seta camera și, în interiorul buclei, vom încărca videoclipul de intrare în modul de tonuri de gri (același lucru pe care l-am văzut înainte).

Acum trebuie să apelăm funcția noastră de clasificare, trecându-i câțiva parametri foarte importanți, precum factorul de scară, numărul vecinilor și dimensiunea minimă a feței detectate.

faces = faceCascade.detectMultiScale (gri, scaleFactor = 1,2, min Vecini = 5, min Dimensiune = (20, 20))

Unde,

  • gri este imaginea introdusă în tonuri de gri.
  • scaleFactor este parametrul care specifică cât este redusă dimensiunea imaginii la fiecare scară a imaginii. Este folosit pentru a crea piramida de scară.
  • minNeighbours este un parametru care specifică câți vecini ar trebui să aibă fiecare dreptunghi candidat, pentru a-l păstra. Un număr mai mare dă fals pozitive mai mici.
  • minSize este dimensiunea minimă a dreptunghiului care trebuie considerată o față.

Funcția va detecta fețele de pe imagine. Apoi, trebuie să „marcăm” fețele din imagine, folosind, de exemplu, un dreptunghi albastru. Acest lucru se face cu această porțiune a codului:

pentru (x, y, w, h) în fețe:

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

Dacă se găsesc fețe, returnează pozițiile fețelor detectate ca un dreptunghi cu colțul din stânga sus (x, y) și având „w” ca lățime și „h” ca înălțime ==> (x, y, w, h). Vă rugăm să consultați imaginea de mai sus.

Odată ce obținem aceste locații, putem crea un „ROI” (dreptunghi desenat) pentru față și să prezentăm rezultatul cu funcția imshow ().

Rulați scriptul python de mai sus pe mediul dvs. python, utilizând terminalul Rpi:

python faceDetection.py

Rezultatul:

Imagine
Imagine

De asemenea, puteți include clasificatoare pentru „detectarea ochilor” sau chiar „detectarea zâmbetului”. În aceste cazuri, veți include funcția de clasificare și desenul dreptunghiular în interiorul buclei feței, deoarece nu ar avea sens să detectați un ochi sau un zâmbet în afara unei fețe.

Rețineți că pe un Pi, având mai mulți clasificatori la același cod va încetini procesarea, odată ce această metodă de detectare (HaarCascades) folosește o cantitate mare de putere de calcul. Pe un desktop, este mai ușor să îl rulați.

Pe GitHub, veți găsi alte exemple:

faceEyeDetection.py

faceSmileDetection.py

faceSmileEyeDetection.py

Și în imaginea de mai sus, puteți vedea rezultatul.

De asemenea, puteți urma tutorialul de mai jos pentru a înțelege mai bine Detectarea feței:

Haar Cascade Detectarea obiectelor Tutorial OpenCV Python pentru față și ochi

Pasul 5: Colectarea datelor

Colectarea datelor
Colectarea datelor
Colectarea datelor
Colectarea datelor

În primul rând, trebuie să-i mulțumesc lui Ramiz Raja pentru munca sa minunată în recunoașterea feței pe fotografii:

RECUNOAȘTERE FACIALĂ FOLOSIND OPENCV ȘI PITON: GHID DE ÎNCEPUT

și, de asemenea, Anirban Kar, care a dezvoltat un tutorial foarte cuprinzător folosind videoclipuri:

RECUNOAȘTERE FACIALĂ - 3 părți

Vă recomand cu adevărat să aruncați o privire la ambele tutoriale.

Spunând asta, să începem prima fază a proiectului nostru. Ceea ce vom face aici, începe de la ultimul pas (Face Detection), vom crea pur și simplu un set de date, unde vom stoca pentru fiecare id, un grup de fotografii în gri cu porțiunea care a fost utilizată pentru detectarea feței.

Mai întâi, creați un director în care vă dezvoltați proiectul, de exemplu, FacialRecognitionProject:

mkdir FacialRecognitionProject

În acest director, pe lângă cele 3 scripturi python pe care le vom crea pentru proiectul nostru, trebuie să fi salvat pe el Clasificatorul Facial. Îl puteți descărca din GitHub: haarcascade_frontalface_default.xml

Apoi, creați un subdirector în care vom stoca probele noastre faciale și îl vom denumi „set de date”:

mkdir set de date

Și descărcați codul din GitHub: 01_face_dataset.py

import cv2

import os cam = cv2. VideoCapture (0) cam.set (3, 640) # set video width cam.set (4, 480) # set video height face_detector = cv2. CascadeClassifier ('haarcascade_frontalface_default.xml') # Pentru fiecare persoană, introduceți un ID numeric de față face_id = input ('\ n introduceți ID utilizator final apăsați ==>') print ("\ n [INFO] Inițializarea captării feței. Uitați-vă la cameră și așteptați …") # Inițializați numărul de fețe de eșantionare individuală = 0 în timp ce (Adevărat): ret, img = cam.read () img = cv2.flip (img, -1) # flip imagine video vertical gri = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) faces = face_detector.detectMultiScale (gri, 1,3, 5) pentru (x, y, w, h) în fețe: cv2.rectangle (img, (x, y), (x + w, y + h), (255, 0, 0), 2) count + = 1 # Salvați imaginea capturată în folderul seturilor de date cv2.imwrite ("set de date / Utilizator." + str (face_id) + '.' + str (count) + ".jpg", gri [y: y + h, x: x + w]) cv2.imshow ('image', img) k = cv2.waitKey (100) & 0xff # Apăsați 'ESC' pentru a ieși din videoclip dacă k == 27: rupe numărul de elif> = 30: # Luați 30 de mostre de față și opriți pauza video # Faceți ab it of cleanup print ("\ n [INFO] Programul de ieșire și lucrurile de curățare") cam.release () cv2.destroyAllWindows ()

Codul este foarte asemănător cu cel pe care l-am văzut pentru detectarea feței. Ceea ce am adăugat a fost o „comandă de intrare” pentru a captura un ID de utilizator, care ar trebui să fie un număr întreg (1, 2, 3 etc.)

face_id = input ('\ n introduceți ID utilizator final apăsați ==>')

Și pentru fiecare dintre cadrele capturate, ar trebui să îl salvăm ca fișier într-un director „set de date”:

cv2.imwrite ("set de date / utilizator." + str (face_id) + '.' + str (count) + ".jpg", gri [y: y + h, x: x + w])

Rețineți că pentru salvarea fișierului de mai sus, trebuie să fi importat biblioteca "os". Numele fiecărui fișier va urma structura:

User.face_id.count.jpg

De exemplu, pentru un utilizator cu un face_id = 1, al patrulea fișier eșantion din setul de date / director va fi ceva de genul:

Utilizator.1.4.jpg

așa cum se arată în fotografia de mai sus din Pi. În codul meu, capturez 30 de mostre din fiecare ID. Îl puteți schimba pe ultimul „elif”. Numărul de eșantioane este utilizat pentru a rupe bucla în care sunt capturate probele de față.

Rulați scriptul Python și capturați câteva ID-uri. Trebuie să rulați scriptul de fiecare dată când doriți să agregați un utilizator nou (sau să schimbați fotografiile pentru unul care există deja).

Pasul 6: antrenor

Antrenor
Antrenor

În această a doua fază, trebuie să preluăm toate datele utilizatorului din setul nostru de date și să „formăm” OpenCV Recognizer. Acest lucru este realizat direct de o anumită funcție OpenCV. Rezultatul va fi un fișier.yml care va fi salvat într-un director „trainer /”.

Deci, să începem să creăm un subdirector unde vom stoca datele instruite:

antrenor mkdir

Descărcați din GitHub al doilea script python: 02_face_training.py

import cv2

import numpy as np from PIL import Image os os # Path for face image database path = 'dataset' recognizer = cv2.face. LBPHFaceRecognizer_create () detector = cv2. CascadeClassifier ("haarcascade_frontalface_default.xml"); # funcție pentru a obține imaginile și eticheta datele def getImagesAndLabels (cale): imagePaths = [os.path.join (cale, f) pentru f în os.listdir (cale)] faceSamples = ids = pentru imagePath în imagePaths: PIL_img = Image.open (imagePath).convert ('L') # convertește-o în tonuri de gri 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] Fețe de antrenament. Va dura câteva secunde. Așteptați …") fețe, ids = getImagesAndLabels (cale) recognizer.train (fețe, np.array (ids)) # Salvați modelul în trainer / trainer.yml recognizer.write ('trainer / trainer.yml') # recognizer.save () a funcționat pe Mac, dar nu pe Pi # Imprimați numărul de fețe antrenate și terminați programul de imprimare ("\ n [INFO] {0} fețe antrenate. Programul de ieșire".format (len (np.unique (ids))))

Confirmați dacă aveți biblioteca PIL instalată pe Rpi. Dacă nu, rulați comanda de mai jos în Terminal:

pip instala perna

Vom folosi ca recunoaștere, LBPH (LOCAL BINARY PATTERNS HISTOGRAMS) Face Recognizer, inclus pe pachetul OpenCV. Facem acest lucru în următoarea linie:

recognizer = cv2.face. LBPHFaceRecognizer_create ()

Funcția „getImagesAndLabels (cale)”, va face toate fotografiile din director: „set de date /”, returnând 2 matrici: „Id-uri” și „fețe”. Având aceste matrici ca intrare, ne vom „instrui recunoscătorul”:

recognizer.train (fețe, id-uri)

Ca urmare, un fișier numit „trainer.yml” va fi salvat în directorul de antrenor care a fost creat anterior de noi.

Asta e! Am inclus ultima declarație tipărită în care am afișat pentru confirmare, numărul fețelor utilizatorului pe care le-am antrenat.

De fiecare dată când efectuați faza 1, faza 2 trebuie, de asemenea, să fie rulată

Pasul 7: Recunoscător

Recunoscător
Recunoscător
Recunoscător
Recunoscător

Acum am ajuns la faza finală a proiectului nostru. Aici, vom surprinde o față proaspătă pe camera noastră și, dacă această persoană a avut fața capturată și antrenată înainte, identificatorul nostru va face o „predicție” care îi va reda identitatea și un index, arătând cât de încrezător este recunoscătorul în acest meci.

Să descărcăm scriptul Python din a treia fază din GitHub: 03_face_recognition.py.

import 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 # nume legate de id-uri: exemplu ==> Marcelo: id = 1, etc names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z ',' W '] # Inițializați și începeți captarea video în timp real cam = cv2. VideoCapture (0) cam.set (3, 640) # set video widht cam.set (4, 480) # set video height # Definirea dimensiunii min a ferestrei să fie recunoscut ca o față minW = 0,1 * cam.get (3) minH = 0,1 * cam.get (4) în timp ce True: ret, img = cam.read () img = cv2.flip (img, -1) # Răsuciți vertical gri = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) fețe = faceCascade.detectMultiScale (gri, scaleFactor = 1.2, minNeighbours = 5, minSize = (int (minW), int (minH)),) pentru (x, y, w, h) în fețe: cv2.rectangle (img, (x, y), (x + w, y + h), (0, 255, 0), 2) id, încredere = recognizer.predict (gri [y: y + h, x: x + w]) # Verificați dacă încrederea este mai mică de ele 100 ==> "0" este potrivirea perfectă dacă (încredere <100): id = nume [id] încredere = "{0}% ".format (rotund (100 - încredere)) else: id =" necunoscut "încredere =" {0}% ". format (rotund (100 - conf) idence)) cv2.putText (img, str (id), (x + 5, y-5), font, 1, (255, 255, 255), 2) cv2.putText (img, str (încredere), (x + 5, y + h-5), font, 1, (255, 255, 0), 1) cv2.imshow („camera”, img) k = cv2.waitKey (10) & 0xff # Apăsați „ESC” pentru ieșirea din videoclip dacă k == 27: pauză # Faceți un pic de curățare tipărită ("\ n [INFO] Ieșirea din program și lucruri de curățare") cam.release () cv2.destroyAllWindows ()

Includem aici o nouă matrice, așa că vom afișa „nume”, în loc de ID-uri numerotate:

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

Deci, de exemplu: Marcelo va folosi utilizatorul cu id = 1; Paula: id = 2, etc.

Apoi, vom detecta o față, așa cum am făcut înainte cu clasificatorul haasCascade. Având o față detectată, putem apela cea mai importantă funcție din codul de mai sus:

id, încredere = recognizer.predict (porțiune gri a feței)

Recunoscătorul.predict (), va lua ca parametru o porțiune capturată a feței care urmează să fie analizată și îi va returna proprietarul probabil, indicând id-ul și cât de multă încredere are recunoașterea în legătură cu această potrivire.

Rețineți că indicele de încredere va reveni la „zero” dacă va fi considerat o potrivire perfectă

Și în cele din urmă, dacă identificatorul ar putea prezice o față, vom pune un text peste imagine cu ID-ul probabil și cât este „probabilitatea” în% ca potrivirea să fie corectă („probabilitate” = 100 - indicele de încredere). Dacă nu, pe față se pune o etichetă „necunoscut”.

Sub un-g.webp

Imagine
Imagine

În imaginea de mai sus, arăt câteva teste efectuate cu acest proiect, unde am folosit și fotografii pentru a verifica dacă funcționează recunoașterea.

Pasul 8: Concluzie

Concluzie
Concluzie

Ca întotdeauna, sper că acest proiect îi poate ajuta pe ceilalți să își găsească drumul în lumea interesantă a electronicii!

Pentru detalii și cod final, vă rugăm să vizitați depozitarul GitHub: OpenCV-Face-Recognition

Pentru mai multe proiecte, vă rugăm să vizitați blogul meu: MJRoBot.org

Mai jos o privire asupra unui viitor tutorial, în care vom explora „pista automată a feței și alte metode de detectare a feței”:

Imagine
Imagine

Salude din sudul lumii!

Ne vedem în următorul meu instructabil!

Mulțumesc, Marcelo

Recomandat: