Indholdsfortegnelse:

Ansigtsgenkendelse i realtid: et ende-til-ende-projekt: 8 trin (med billeder)
Ansigtsgenkendelse i realtid: et ende-til-ende-projekt: 8 trin (med billeder)

Video: Ansigtsgenkendelse i realtid: et ende-til-ende-projekt: 8 trin (med billeder)

Video: Ansigtsgenkendelse i realtid: et ende-til-ende-projekt: 8 trin (med billeder)
Video: freelance artist secret to success (shocking) 2024, Juli
Anonim
Ansigtsgenkendelse i realtid: et projekt fra ende til anden
Ansigtsgenkendelse i realtid: et projekt fra ende til anden

På min sidste tutorial, der udforskede OpenCV, lærte vi AUTOMATIC VISION OBJECT TRACKING. Nu vil vi bruge vores PiCam til at genkende ansigter i realtid, som du kan se nedenfor:

Billede
Billede

Dette projekt blev udført med dette fantastiske "Open Source Computer Vision Library", OpenCV. I denne vejledning fokuserer vi på Raspberry Pi (altså Raspbian som OS) og Python, men jeg testede også koden på min Mac, og den fungerer også fint. OpenCV er designet til beregningseffektivitet og med et stærkt fokus på applikationer i realtid. Så det er perfekt til ansigtsgenkendelse i realtid ved hjælp af et kamera.

For at oprette et komplet projekt om ansigtsgenkendelse skal vi arbejde på 3 meget forskellige faser:

  1. Ansigtsregistrering og dataindsamling
  2. Træn genkenderen
  3. Ansigtsgenkendelse

Nedenstående blokdiagram genoptager disse faser:

Billede
Billede

Trin 1: BoM - regning af materiale

Hoveddele:

  1. Raspberry Pi V3 - 32,00 US $
  2. 5 megapixel 1080p sensor OV5647 mini kamera videomodul - 13,00 US $

Trin 2: Installation af OpenCV 3 -pakken

Installation af OpenCV 3 -pakken
Installation af OpenCV 3 -pakken

Jeg bruger en Raspberry Pi V3 opdateret til den sidste version af Raspbian (Stretch), så den bedste måde at få OpenCV installeret på er at følge den fremragende vejledning udviklet af Adrian Rosebrock: Raspbian Stretch: Installer OpenCV 3 + Python på din Raspberry Pi.

Jeg prøvede flere forskellige guider til at installere OpenCV på min Pi. Adrians tutorial er den bedste. Jeg råder dig til at gøre det samme ved at følge hans retningslinje trin for trin.

Når du er færdig med Adrians tutorial, skal du have et virtuelt OpenCV -miljø klar til at køre vores eksperimenter på din Pi.

Lad os gå til vores virtuelle miljø og bekræfte, at OpenCV 3 er korrekt installeret.

Adrian anbefaler, at du kører kommandoen "kilde", hver gang du åbner en ny terminal for at sikre, at dine systemvariabler er konfigureret korrekt.

kilde ~/.profil

Lad os derefter gå ind på vores virtuelle miljø:

arbejdet cv

Hvis du ser teksten (cv) forud for din prompt, befinder du dig i det virtuelle cv -miljø:

(cv) pi@hindbær: ~ $Adrian henleder opmærksomheden på, at det virtuelle cv Python -miljø er helt uafhængigt og afsondret fra standard Python -version inkluderet i download af Raspbian Stretch. Så alle Python-pakker i den globale site-packages-bibliotek vil ikke være tilgængelige for cv-virtuelle miljø. På samme måde vil alle Python-pakker, der er installeret i sted-pakker med cv, ikke være tilgængelige for den globale installation af Python

Indtast nu din Python -tolk:

python

og bekræft, at du kører versionen 3.5 (eller nyere)

Inde i tolken (">>>" vises), importer OpenCV -biblioteket:

import cv2

Hvis der ikke vises nogen fejlmeddelelser, er OpenCV korrekt installeret PÅ DIN PYTHON VIRTUAL MILJØ.

Du kan også kontrollere den installerede OpenCV -version:

cv2._ version_

3.3.0 skal vises (eller en overlegen version, der kan frigives i fremtiden). Ovenstående Terminal PrintScreen viser de foregående trin.

Trin 3: Testning af dit kamera

Test af dit kamera
Test af dit kamera

Når du har installeret OpenCV i din RPi, lad os teste for at bekræfte, at dit kamera fungerer korrekt.

Jeg går ud fra, at du allerede har en PiCam installeret på din Raspberry Pi.

Indtast nedenstående Python -kode på din IDE:

import numpy som 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 (ramme, -1) # Flip kamera lodret grå = cv2.cvtColor (frame, cv2. COLOR_BGR2GRAY) cv2.imshow ('frame', frame) cv2.imshow ('grå', grå) k = cv2.waitKey (30) & 0xff hvis k == 27: # tryk på 'ESC' for at afbryde break cap.release () cv2.destroyAllWindows ()

Ovenstående kode fanger den videostream, der genereres af din PiCam, og viser begge i BGR -farve og grå tilstand.

Bemærk, at jeg roterede mit kamera lodret på grund af den måde, det er samlet på. Hvis det ikke er din sag, skal du kommentere eller slette kommandolinjen "flip".

Du kan alternativt downloade koden fra min GitHub: simpleCamTest.py

For at udføre skal du indtaste kommandoen:

python simpleCamTest.py

For at afslutte programmet skal du trykke på tasten [ESC] på dit tastatur.

Klik med musen på videovinduet, før du trykker på [ESC]

Ovenstående billede viser resultatet.

Nogle producenter fandt problemer, når de forsøgte at åbne kameraet ("Bekræftelse mislykkedes" fejlmeddelelser). Det kan ske, hvis kameraet ikke var aktiveret under OpenCv -installationen, og kameraer blev derfor ikke installeret korrekt. For at rette, brug kommandoen:

sudo modprobe bcm2835-v4l2

Du kan også tilføje bcm2835-v4l2 til den sidste linje i filen /etc /modules, så driveren indlæses ved opstart.

Hvis du vil vide mere om OpenCV, kan du følge selvstudiet: loading -video-python-opencv-tutorial

Trin 4: Ansigtsregistrering

Ansigtsregistrering
Ansigtsregistrering
Ansigtsregistrering
Ansigtsregistrering

Den mest grundlæggende opgave ved ansigtsgenkendelse er naturligvis "Ansigtsregistrering". Før noget skal du "fange" et ansigt (fase 1) for at genkende det, sammenlignet med et nyt ansigt, der er fanget i fremtiden (fase 3).

Den mest almindelige måde at registrere et ansigt (eller andre objekter) på er ved hjælp af "Haar Cascade classifier"

Objektdetektion ved hjælp af Haar-funktionsbaserede kaskadeklassificatorer er en effektiv objektdetekteringsmetode foreslået af Paul Viola og Michael Jones i deres papir, "Rapid Object Detection using a Boosted Cascade of Simple Features" i 2001. Det er en machine learning-baseret tilgang, hvor en kaskadefunktion er trænet ud fra en masse positive og negative billeder. Det bruges derefter til at registrere objekter i andre billeder.

Her vil vi arbejde med ansigtsgenkendelse. I første omgang har algoritmen brug for en masse positive billeder (billeder af ansigter) og negative billeder (billeder uden ansigter) for at træne klassifikatoren. Derefter skal vi udtrække funktioner fra det. Den gode nyhed er, at OpenCV kommer med en træner såvel som en detektor. Hvis du vil træne din egen klassifikator for ethvert objekt som bil, fly osv., Kan du bruge OpenCV til at oprette en. Dens fulde detaljer er givet her: Cascade Classifier Training.

Hvis du ikke ønsker at oprette din egen klassifikator, indeholder OpenCV allerede mange foruddannede klassifikatorer til ansigt, øjne, smil osv. Disse XML-filer kan downloades fra haarcascades bibliotek.

Nok teori, lad os oprette en ansigtsdetektor med OpenCV!

Download filen: faceDetection.py fra min GitHub.

import numpy som np

import cv2 faceCascade = cv2. CascadeClassifier ('Cascades/haarcascade_frontalface_default.xml') cap = cv2. VideoCapture (0) cap.set (3, 640) # set Width cap.set (4, 480) # set Højde mens True: ret, img = cap.read () img = cv2.flip (img, -1) grå = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansigter = faceCascade.detectMultiScale (grå, scaleFactor = 1.2, minNeighbors = 5, minSize = (20, 20)) for (x, y, w, h) i ansigter: cv2.rektangel (img, (x, y), (x+w, y+h), (255, 0, 0), 2) roi_gray = grå [y: y+h, x: x+w] roi_color = img [y: y+h, x: x+w] cv2.imshow ('video', img) k = cv2.waitKey (30) & 0xff hvis k == 27: # tryk på 'ESC' for at afslutte break cap.release () cv2.destroyAllWindows ()

Tro det eller ej, ovenstående få linjer med kode er alt, hvad du har brug for for at registrere et ansigt ved hjælp af Python og OpenCV.

Når du sammenligner med den sidste kode, der blev brugt til at teste kameraet, vil du indse, at få dele blev tilføjet til det. Bemærk nedenstående linje:

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

Dette er den linje, der indlæser "klassifikatoren" (der skal være i et bibliotek med navnet "Cascades/", under dit projektmappe).

Derefter vil vi indstille vores kamera og inde i sløjfen indlæse vores inputvideo i gråtonetilstand (samme som vi så før).

Nu skal vi kalde vores klassificeringsfunktion og give den nogle meget vigtige parametre, som skalafaktor, antal naboer og minimumsstørrelse på det registrerede ansigt.

ansigter = faceCascade.detectMultiScale (grå, skalaFaktor = 1,2, minNaboer = 5, minStørrelse = (20, 20))

Hvor,

  • grå er input -gråtonebilledet.
  • scaleFactor er parameteren, der angiver, hvor meget billedstørrelsen reduceres ved hver billedskala. Det bruges til at skabe skala -pyramiden.
  • minNeighbors er en parameter, der angiver, hvor mange naboer hvert kandidatrektangel skal have for at beholde det. Et højere tal giver lavere falske positiver.
  • minSize er den mindste rektangelstørrelse, der skal betragtes som et ansigt.

Funktionen registrerer ansigter på billedet. Dernæst skal vi "markere" ansigterne i billedet ved hjælp af f.eks. Et blåt rektangel. Dette gøres med denne del af koden:

for (x, y, w, h) i ansigter:

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

Hvis der findes ansigter, returnerer det positionerne for detekterede ansigter som et rektangel med venstre hjørne op (x, y) og med "w" som bredde og "h" som højde ==> (x, y, w, h). Se venligst ovenstående billede.

Når vi får disse placeringer, kan vi oprette et "ROI" (tegnet rektangel) til ansigtet og præsentere resultatet med imshow () -funktionen.

Kør ovenstående python -script i dit python -miljø ved hjælp af Rpi Terminal:

python faceDetection.py

Resultatet:

Billede
Billede

Du kan også inkludere klassifikatorer til "øjensøgning" eller endda "smilregistrering". I disse tilfælde vil du inkludere klassificeringsfunktionen og rektangeltegning inde i ansigtsløkken, for det ville ikke være fornuftigt at registrere et øje eller et smil uden for et ansigt.

Bemærk, at på en Pi vil flere klassificatorer ved samme kode forsinke behandlingen, når denne detektionsmetode (HaarCascades) bruger en stor mængde beregningseffekt. På et skrivebord er det lettere at køre det.

På min GitHub finder du andre eksempler:

faceEyeDetection.py

faceSmileDetection.py

faceSmileEyeDetection.py

Og på billedet ovenfor kan du se resultatet.

Du kan også følge nedenstående vejledning for bedre at forstå ansigtsgenkendelse:

Haar Cascade Object Detection Ansigt og øje OpenCV Python -vejledning

Trin 5: Dataindsamling

Data indsamling
Data indsamling
Data indsamling
Data indsamling

Først og fremmest skal jeg takke Ramiz Raja for hans store arbejde med ansigtsgenkendelse på fotos:

ANSIGTSANKENDELSE VED AT BRUGE OPENCV OG PYTHON: EN BEGYNDERVEJLEDNING

og også Anirban Kar, der udviklede en meget omfattende tutorial ved hjælp af video:

ANSIGTSANKENDELSE - 3 dele

Jeg anbefaler virkelig, at du kigger på begge tutorials.

Når det er sagt, lad os starte den første fase af vores projekt. Hvad vi vil gøre her, starter fra sidste trin (Ansigtsregistrering), vi vil simpelthen oprette et datasæt, hvor vi for hvert id gemmer en gruppe billeder i gråt med den del, der blev brugt til ansigtsregistrering.

Opret først et bibliotek, hvor du udvikler dit projekt, for eksempel FacialRecognitionProject:

mkdir FacialRecognitionProject

I denne mappe, udover de 3 python -scripts, som vi vil oprette til vores projekt, skal vi have gemt Facial Classifier på den. Du kan downloade den fra min GitHub: haarcascade_frontalface_default.xml

Opret derefter en underkatalog, hvor vi vil gemme vores ansigtsprøver og navngive det "datasæt":

mkdir datasæt

Og download koden fra min 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') # For hver person, indtast et numerisk ansigt -id face_id = input ('\ n indtast bruger -id slut tryk ==>') udskriv ("\ n [INFO] Initialiserer ansigtsoptagelse. Se på kameraet og vent …") # Initialiser individuelle samplingtællinger = 0 mens (True): ret, img = cam.read () img = cv2.flip (img, -1) # flip videobillede lodret gråt = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansigter = face_detector.detectMultiScale (grå, 1,3, 5) for (x, y, w, h) i ansigter: cv2.rektangel (img, (x, y), (x+w, y+h), (255, 0, 0), 2) count + = 1 # Gem det optagede billede i datasætmappen cv2.imwrite ("datasæt/bruger." + str (face_id) + '.' + str (count) + ".jpg", grå [y: y + h, x: x+w]) cv2.imshow ('image', img) k = cv2.waitKey (100) & 0xff # Tryk på 'ESC' for at afslutte video, hvis k == 27: break elif count> = 30: # Tag 30 ansigtsprøver og stop videopause # Gør ab det af oprydningstryk ("\ n [INFO] Afslutter program og oprydningsting") cam.release () cv2.destroyAllWindows ()

Koden ligner meget den kode, vi så til ansigtsgenkendelse. Det, vi tilføjede, var en "inputkommando" for at fange et bruger -id, der skulle være et helt tal (1, 2, 3 osv.)

face_id = input ('\ n indtast bruger -id slut tryk ==>')

Og for hver enkelt af de fangede rammer skulle vi gemme den som en fil i et "datasæt" bibliotek:

cv2.imwrite ("datasæt/bruger." + str (face_id) + '.' + str (count) + ".jpg", grå [y: y + h, x: x + w])

Bemærk, at for at gemme ovenstående fil skal du have importeret biblioteket "os". Hver fils navn følger strukturen:

User.face_id.count.jpg

For eksempel for en bruger med et face_id = 1 vil den fjerde prøvefil på datasæt/ bibliotek være sådan:

Bruger.1.4.jpg

som vist på ovenstående foto fra min Pi. På min kode optager jeg 30 prøver fra hvert id. Du kan ændre det på den sidste "elif". Antallet af prøver bruges til at bryde sløjfen, hvor ansigtsprøverne fanges.

Kør Python -scriptet, og tag et par id'er. Du skal køre scriptet hver gang, du vil samle en ny bruger (eller ændre fotos for et, der allerede findes).

Trin 6: Træner

Træner
Træner

I denne anden fase skal vi tage alle brugerdata fra vores datasæt og "træne" OpenCV Recognizer. Dette gøres direkte af en specifik OpenCV -funktion. Resultatet vil være en.yml -fil, der vil blive gemt i et "træner/" bibliotek.

Så lad os begynde at oprette en underkatalog, hvor vi vil gemme de uddannede data:

mkdir træner

Download det andet python -script fra min GitHub: 02_face_training.py

import cv2

import numpy som np fra PIL import Billedimport os # Sti til ansigtsbilleddatabasesti = 'datasæt' genkender = cv2.face. LBPHFaceRecognizer_create () detektor = cv2. CascadeClassifier ("haarcascade_frontalface_default.xml"); # funktion for at hente billederne og mærke data def getImagesAndLabels (sti): imagePaths = [os.path.join (sti, f) for f i os.listdir (sti)] faceSamples = ids = for imagePath i imagePaths: PIL_img = Image.open (imagePath).convert ('L') # konverter det til gråtoner img_numpy = np.array (PIL_img, 'uint8') id = int (os.path.split (imagePath) [-1]. split (".") [1]) ansigter = detektor.detectMultiScale (img_numpy) for (x, y, w, h) i ansigter: faceSamples.append (img_numpy [y: y+h, x: x+w]) ids.append (id) return faceSamples, ids print ("\ n [INFO] Træningsflader. Det vil tage et par sekunder. Vent …") ansigter, ids = getImagesAndLabels (sti) anerkender.train (ansigter, np.array (ids)) # Gem modellen i trainer/trainer.yml anerkender.skrive ('træner/træner.yml') # genkender.save () arbejdede på Mac, men ikke på Pi # Udskriv antallet af ansigter, der er uddannet, og afslut programudskrivning ("\ n [INFO] {0} uddannede ansigter. Afslutter program".format (len (np.unique (ids))))

Bekræft, om du har PIL -biblioteket installeret på din Rpi. Hvis ikke, skal du køre nedenstående kommando i Terminal:

pip installer pude

Vi vil bruge som en genkender LBPH (LOCAL BINARY PATTERNS HISTOGRAMS) Face Recognizer, der er inkluderet i OpenCV -pakken. Vi gør dette i følgende linje:

anerkender = cv2.face. LBPHFaceRecognizer_create ()

Funktionen "getImagesAndLabels (sti)", vil tage alle fotos på biblioteket: "datasæt/" og returnere 2 arrays: "Ids" og "ansigter". Med disse arrays som input vil vi "træne vores genkender":

anerkender.træning (ansigter, id'er)

Som et resultat vil en fil med navnet "trainer.yml" blive gemt i trænermappen, der tidligere blev oprettet af os.

Det er det! Jeg inkluderede den sidste udskrivningserklæring, hvor jeg viste for bekræftelse, antallet af brugerens ansigter, vi har trænet.

Hver gang du udfører fase 1, skal fase 2 også køres

Trin 7: Genkender

Genkender
Genkender
Genkender
Genkender

Nu nåede vi den sidste fase af vores projekt. Her vil vi fange et nyt ansigt på vores kamera, og hvis denne person havde fået sit ansigt fanget og trænet før, vil vores genkender lave en "forudsigelse", der returnerer sit id og et indeks, vist hvor sikker genkenderen er med denne kamp.

Lad os downloade 3. fase python script fra mit GitHub: 03_face_recognition.py.

import cv2

import numpy as np import os anerkender = cv2.face. LBPHFaceRecognizer_create () anerkender.read ('trainer/trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2. CascadeClassifier (cascadePath); font = cv2. FONT_HERSHEY_SIMPLEX #iniciate id counter id = 0 # names related to ids: example ==> Marcelo: id = 1, etc names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z ',' W '] # Initialiser og start realtime video capture cam = cv2. VideoCapture (0) cam.set (3, 640) # sæt video widht cam.set (4, 480) # indstil videohøjde # Definer min vinduesstørrelse skal genkendes som et ansigt minW = 0,1*cam.get (3) minH = 0,1*cam.get (4) mens True: ret, img = cam.read () img = cv2.flip (img, -1) # Vend lodret grå = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansigter = faceCascade.detectMultiScale (grå, scaleFactor = 1.2, minNeighbors = 5, minSize = (int (minW), int (minH)),) for (x, y, w, h) i ansigter: cv2.rektangel (img, (x, y), (x+w, y+h), (0, 255, 0), 2) id, tillid = anerkender. forudsigelse (grå [y: y+h, x: x+w]) # Kontroller, om tilliden er mindre dem 100 ==> "0" er perfekt match, hvis (tillid <100): id = navne [id] tillid = "{0}% ".format (runde (100 - konfidens)) else: id =" ukendt "tillid =" {0}%". format (runde (100 - konf. idence)) cv2.putText (img, str (id), (x+5, y-5), font, 1, (255, 255, 255), 2) cv2.putText (img, str (tillid), (x+5, y+h-5), skrifttype, 1, (255, 255, 0), 1) cv2.imshow ('kamera', img) k = cv2.waitKey (10) & 0xff # Tryk på 'ESC' for at forlade video, hvis k == 27: pause # Lav en smule oprydningsprint ("\ n [INFO] Afslutning af program og oprydning") cam.release () cv2.destroyAllWindows ()

Vi inkluderer her et nyt array, så vi vil vise "navne" i stedet for nummererede id'er:

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

Så for eksempel: Marcelo vil brugeren med id = 1; Paula: id = 2 osv.

Dernæst vil vi registrere et ansigt, det samme som vi gjorde før med haasCascade -klassifikatoren. Når vi har et registreret ansigt, kan vi kalde den vigtigste funktion i ovenstående kode:

id, tillid = genkender. forudsigelse (grå del af ansigtet)

Recognizer.predict (), tager som en parameter en fanget del af ansigtet, der skal analyseres, og returnerer den sandsynlige ejer, hvilket angiver dens id og hvor stor tillid genkenderen har i forhold til denne kamp.

Bemærk, at konfidensindekset returnerer "nul", hvis det betragtes som et perfekt match

Og endelig, hvis genkenderen kunne forudsige et ansigt, satte vi en tekst over billedet med det sandsynlige id, og hvor meget er "sandsynligheden" i %, at matchen er korrekt ("sandsynlighed" = 100 - konfidensindeks). Hvis ikke, sættes en "uvidende" etiket på ansigtet.

Nedenfor en-g.webp

Billede
Billede

På ovenstående billede viser jeg nogle tests udført med dette projekt, hvor jeg også har brugt fotos til at kontrollere, om genkenderen fungerer.

Trin 8: Konklusion

Konklusion
Konklusion

Som altid håber jeg, at dette projekt kan hjælpe andre med at finde vej til den spændende elektronikverden!

For detaljer og endelig kode, besøg mit GitHub-depot: OpenCV-Face-Recognition

For flere projekter, besøg min blog: MJRoBot.org

Nedenfor et glimt af en fremtidig vejledning, hvor vi vil undersøge "automatisk ansigtsspor og andre metoder til ansigtsgenkendelse":

Billede
Billede

Saludos fra den sydlige del af verden!

Vi ses i min næste instruerbare!

Tak skal du have, Marcelo

Anbefalede: