Innholdsfortegnelse:

Ansiktsgjenkjenning i sanntid: et ende-til-ende-prosjekt: 8 trinn (med bilder)
Ansiktsgjenkjenning i sanntid: et ende-til-ende-prosjekt: 8 trinn (med bilder)

Video: Ansiktsgjenkjenning i sanntid: et ende-til-ende-prosjekt: 8 trinn (med bilder)

Video: Ansiktsgjenkjenning i sanntid: et ende-til-ende-prosjekt: 8 trinn (med bilder)
Video: Лео Гура: Бесконечное сознание, реализация Бога [ЧАСТЬ 1] 2024, Juli
Anonim
Ansiktsgjenkjenning i sanntid: et ende-til-ende-prosjekt
Ansiktsgjenkjenning i sanntid: et ende-til-ende-prosjekt

På min siste opplæring som utforsket OpenCV, lærte vi AUTOMATIC VISION OBJECT TRACKING. Nå skal vi bruke PiCam til å gjenkjenne ansikter i sanntid, som du kan se nedenfor:

Bilde
Bilde

Dette prosjektet ble utført med dette fantastiske "Open Source Computer Vision Library", OpenCV. På denne opplæringen vil vi fokusere på Raspberry Pi (altså Raspbian som OS) og Python, men jeg testet også koden på min Mac, og den fungerer også bra. OpenCV ble designet for beregningseffektivitet og med stort fokus på sanntidsapplikasjoner. Så det er perfekt for ansiktsgjenkjenning i sanntid ved hjelp av et kamera.

For å lage et komplett prosjekt om ansiktsgjenkjenning, må vi jobbe med tre veldig forskjellige faser:

  1. Ansiktsgjenkjenning og datasamling
  2. Tren treneren
  3. Ansiktsgjenkjenning

Blokkediagrammet nedenfor gjenopptar disse fasene:

Bilde
Bilde

Trinn 1: BoM - materialregning

Hoved deler:

  1. Raspberry Pi V3 - 32,00 dollar
  2. 5 megapiksler 1080p sensor OV5647 minikamera videomodul - USD 13,00

Trinn 2: Installere OpenCV 3 -pakken

Installere OpenCV 3 -pakken
Installere OpenCV 3 -pakken

Jeg bruker en Raspberry Pi V3 oppdatert til den siste versjonen av Raspbian (Stretch), så den beste måten å ha OpenCV installert på er å følge den utmerkede opplæringen utviklet av Adrian Rosebrock: Raspbian Stretch: Installer OpenCV 3 + Python på din Raspberry Pi.

Jeg prøvde flere forskjellige guider for å installere OpenCV på min Pi. Adrians opplæring er den beste. Jeg råder deg til å gjøre det samme ved å følge retningslinjene hans trinn for trinn.

Når du er ferdig med Adrians opplæring, bør du ha et virtuelt OpenCV -miljø klar til å kjøre eksperimentene våre på Pi.

La oss gå til vårt virtuelle miljø og bekrefte at OpenCV 3 er riktig installert.

Adrian anbefaler at du kjører kommandoen "kilde" hver gang du åpner en ny terminal for å sikre at systemvariablene er konfigurert riktig.

kilde ~/.profil

La oss deretter gå inn på vårt virtuelle miljø:

workon cv

Hvis du ser teksten (cv) foran ledeteksten, befinner du deg i det virtuelle cv -miljøet:

(cv) pi@bringebær: ~ $Adrian viser oppmerksomheten til at det virtuelle cv Python -miljøet er helt uavhengig og avskåret fra standard Python -versjon som er inkludert i nedlastingen av Raspbian Stretch. Så alle Python-pakker i den globale nettstedspakekatalogen vil ikke være tilgjengelige for det virtuelle cv-miljøet. På samme måte vil alle Python-pakker som er installert i stedspakker med cv, ikke være tilgjengelige for den globale installasjonen av Python

Skriv nå inn din Python -tolk:

python

og bekreft at du kjører versjonen 3.5 (eller nyere)

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

importer cv2

Hvis det ikke vises noen feilmeldinger, er OpenCV riktig installert PÅ DITT PYTHON VIRTUAL MILJØ.

Du kan også sjekke installert OpenCV -versjon:

cv2._ versjon_

3.3.0 skal vises (eller en overlegen versjon som kan slippes i fremtiden). Terminal PrintScreen ovenfor viser de foregående trinnene.

Trinn 3: Testing av kameraet

Tester kameraet ditt
Tester kameraet ditt

Når du har installert OpenCV i RPi, la oss teste for å bekrefte at kameraet fungerer som det skal.

Jeg antar at du allerede har en PiCam installert på Raspberry Pi.

Skriv inn Python -koden nedenfor på IDE:

importer 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 (frame, -1) # Flip camera vertically grey = cv2.cvtColor (frame, cv2. COLOR_BGR2GRAY) cv2.imshow ('frame', frame) cv2.imshow ('grå', grå) k = cv2.waitKey (30) & 0xff hvis k == 27: # trykk 'ESC' for å avslutte break cap.release () cv2.destroyAllWindows ()

Koden ovenfor vil fange videostrømmen som vil bli generert av PiCam, og vise begge, i BGR -farge og grå modus.

Vær oppmerksom på at jeg roterte kameraet mitt loddrett på grunn av måten det er montert på. Hvis det ikke er ditt tilfelle, kan du kommentere eller slette kommandolinjen "flip".

Du kan alternativt laste ned koden fra min GitHub: simpleCamTest.py

For å utføre, skriv inn kommandoen:

python simpleCamTest.py

For å fullføre programmet må du trykke [ESC] på tastaturet.

Klikk musen på videovinduet før du trykker på [ESC]

Bildet ovenfor viser resultatet.

Noen produsenter fant problemer når de prøvde å åpne kameraet ("Bekreftelse mislyktes" feilmeldinger). Det kan skje hvis kameraet ikke var aktivert under OpenCv -installasjonen, og kameradrivere ikke ble installert riktig. For å korrigere, bruk kommandoen:

sudo modprobe bcm2835-v4l2

Du kan også legge til bcm2835-v4l2 til den siste linjen i filen /etc /modules, slik at driveren lastes opp ved oppstart.

For å vite mer om OpenCV, kan du følge opplæringen: loading -video-python-opencv-tutorial

Trinn 4: Ansiktsgjenkjenning

Ansiktsgjenkjennelse
Ansiktsgjenkjennelse
Ansiktsgjenkjennelse
Ansiktsgjenkjennelse

Den mest grunnleggende oppgaven med ansiktsgjenkjenning er selvfølgelig "Ansiktsgjenkjenning". Før noe må du "fange" et ansikt (fase 1) for å gjenkjenne det, sammenlignet med et nytt ansikt fanget i fremtiden (fase 3).

Den vanligste måten å oppdage et ansikt (eller gjenstander) på er å bruke "Haar Cascade classifier"

Objektdeteksjon ved hjelp av Haar-funksjonsbaserte kaskadeklassifiseringer er en effektiv objektdeteksjonsmetode foreslått av Paul Viola og Michael Jones i sitt papir, "Rapid Object Detection using a Boosted Cascade of Simple Features" i 2001. Det er en maskinlæringsbasert tilnærming der en kaskadefunksjonen er opplært fra mange positive og negative bilder. Den brukes deretter til å oppdage objekter i andre bilder.

Her skal vi jobbe med ansiktsgjenkjenning. I utgangspunktet trenger algoritmen mange positive bilder (bilder av ansikter) og negative bilder (bilder uten ansikter) for å trene klassifisereren. Da må vi trekke ut funksjoner fra den. Den gode nyheten er at OpenCV kommer med både en trener og en detektor. Hvis du vil trene din egen klassifikator for et objekt som bil, fly etc. kan du bruke OpenCV til å lage en. Alle detaljene er gitt her: Cascade Classifier Training.

Hvis du ikke ønsker å lage din egen klassifiseringsprogram, inneholder OpenCV allerede mange forhåndsutdannede klassifisere for ansikt, øyne, smil, etc. Disse XML-filene kan lastes ned fra haarcascades-katalogen.

Nok teori, la oss lage en ansiktsdetektor med OpenCV!

Last ned filen: faceDetection.py fra min GitHub.

importer 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 Height while True: ret, img = cap.read () img = cv2.flip (img, -1) grå = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansikter = faceCascade.detectMultiScale (grå, scaleFactor = 1.2, minNeighbors = 5, minSize = (20, 20)) for (x, y, w, h) i ansikter: 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 if k == 27: # trykk 'ESC' for å avslutte break cap.release () cv2.destroyAllWindows ()

Tro det eller ei, de få kodelinjene ovenfor er alt du trenger for å oppdage et ansikt ved hjelp av Python og OpenCV.

Når du sammenligner med den siste koden som ble brukt for å teste kameraet, vil du innse at få deler ble lagt til. Legg merke til linjen nedenfor:

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

Dette er linjen som laster "klassifisereren" (som må være i en katalog som heter "Cascades/", under prosjektkatalogen).

Deretter setter vi kameraet vårt, og innsiden av sløyfen laster vi inndatavideoen i gråtonemodus (samme som vi så før).

Nå må vi kalle klassifiseringsfunksjonen og gi den noen veldig viktige parametere, som skalafaktor, antall naboer og minimumsstørrelse på det oppdagede ansiktet.

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

Hvor,

  • grå er inngangsbildet i gråtoner.
  • scaleFactor er parameteren som angir hvor mye bildestørrelsen reduseres ved hver bildeskala. Den brukes til å lage skala -pyramiden.
  • minNeighbors er en parameter som angir hvor mange naboer hvert kandidatrektangel skal ha, for å beholde det. Et høyere tall gir lavere falske positiver.
  • minSize er den minste rektangelstørrelsen som skal betraktes som et ansikt.

Funksjonen vil oppdage ansikter på bildet. Deretter må vi "markere" ansiktene i bildet ved å bruke for eksempel et blått rektangel. Dette gjøres med denne delen av koden:

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

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 ansikter blir funnet, returnerer det posisjonene til de oppdagede ansiktene som et rektangel med venstre hjørne opp (x, y) og med "w" som bredde og "h" som høyde ==> (x, y, w, h). Vennligst se bildet ovenfor.

Når vi får disse stedene, kan vi lage en "ROI" (tegnet rektangel) for ansiktet og presentere resultatet med imshow () -funksjonen.

Kjør python -scriptet ovenfor på python -miljøet ditt, ved hjelp av Rpi Terminal:

python faceDetection.py

Resultatet:

Bilde
Bilde

Du kan også inkludere klassifikatorer for "øyedeteksjon" eller til og med "smilgjenkjenning". I disse tilfellene vil du inkludere klassifiseringsfunksjonen og rektangeltegningen inne i ansiktsløyfen, for det ville ikke være fornuftig å oppdage et øye eller et smil utenfor et ansikt.

Vær oppmerksom på at på en Pi vil flere klassifiseringer med samme kode bremse behandlingen, når denne deteksjonsmetoden (HaarCascades) bruker mye beregningskraft. På et skrivebord er det lettere å kjøre det.

På min GitHub finner du andre eksempler:

faceEyeDetection.py

faceSmileDetection.py

faceSmileEyeDetection.py

Og på bildet ovenfor kan du se resultatet.

Du kan også følge opplæringen nedenfor for å bedre forstå ansiktsgjenkjenning:

Haar Cascade Object Detection Face & Eye OpenCV Python -opplæring

Trinn 5: Datainsamling

Datainnsamling
Datainnsamling
Datainnsamling
Datainnsamling

Først og fremst må jeg takke Ramiz Raja for hans flotte arbeid med ansiktsgjenkjenning på bilder:

ANSIKTSKJENNELSE VED Å BRUKE OPENCV OG PYTHON: EN BEGINNERVEILEDNING

og også Anirban Kar, som utviklet en meget omfattende opplæring ved hjelp av video:

ANSIKTSGJENKJENNELSE - 3 deler

Jeg anbefaler virkelig at du tar en titt på begge opplæringsprogrammene.

Når vi sier det, la oss starte den første fasen av prosjektet vårt. Det vi skal gjøre her, starter fra siste trinn (Ansiktsgjenkjenning), vi vil ganske enkelt lage et datasett, hvor vi vil lagre for hver ID en gruppe bilder i grått med delen som ble brukt til ansiktsgjenkjenning.

Opprett først en katalog der du utvikler prosjektet ditt, for eksempel FacialRecognitionProject:

mkdir FacialRecognitionProject

I denne katalogen, i tillegg til de 3 python -skriptene vi skal lage for prosjektet vårt, må vi ha lagret Facial Classifier på den. Du kan laste den ned fra min GitHub: haarcascade_frontalface_default.xml

Deretter lager du en underkatalog der vi vil lagre ansiktsprøver og gi den navnet "datasett":

mkdir datasett

Og last ned koden fra min GitHub: 01_face_dataset.py

importer 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, skriv inn en numerisk ansikts -ID face_id = input ('\ n skriv inn bruker -ID slutt trykk ==>') utskrift ("\ n [INFO] Initialiserer ansiktsopptak. Se på kameraet og vent …") # Initialiser individuelle samplingtall = 0 mens (True): ret, img = cam.read () img = cv2.flip (img, -1) # flip videobild vertikalt grått = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansikter = face_detector.detectMultiScale (grå, 1,3, 5) for (x, y, w, h) i ansikter: cv2.rektangel (img, (x, y), (x+w, y+h), (255, 0, 0), 2) count + = 1 # Lagre det fangede bildet i datasettmappen cv2.imwrite ("datasett/bruker." + str (face_id) + '.' + str (count) + ".jpg", grå [y: y + h, x: x+w]) cv2.imshow ('image', img) k = cv2.waitKey (100) & 0xff # Trykk på 'ESC' for å gå ut av videoen hvis k == 27: break elif count> = 30: # Ta 30 ansiktsprøver og stopp videopause # Gjør ab det med oppryddingsutskrift ("\ n [INFO] Avslutter program og opprydding") cam.release () cv2.destroyAllWindows ()

Koden er veldig lik koden som vi så for ansiktsgjenkjenning. Det vi la til, var en "input -kommando" for å fange en bruker -ID, som skal være et heltall (1, 2, 3, etc)

face_id = input ('\ n skriv inn bruker -ID, trykk ==>')

Og for hver av de fangede bildene bør vi lagre den som en fil i en "datasett" -katalog:

cv2.imwrite ("datasett/bruker." + str (face_id) + '.' + str (count) + ".jpg", grå [y: y + h, x: x + w])

Vær oppmerksom på at for å lagre filen ovenfor, må du ha importert biblioteket "os". Hver fils navn vil følge strukturen:

User.face_id.count.jpg

For eksempel, for en bruker med en face_id = 1, vil den fjerde prøvefilen på datasettet/ katalogen være omtrent som:

Bruker.1.4.jpg

som vist på bildet ovenfor fra min Pi. På koden min fanger jeg 30 prøver fra hver id. Du kan endre den på den siste "elifen". Antall prøver brukes til å bryte sløyfen der ansiktsprøvene blir tatt.

Kjør Python -skriptet og ta noen få ID -er. Du må kjøre skriptet hver gang du vil samle en ny bruker (eller for å endre bildene for et som allerede eksisterer).

Trinn 6: Trener

Trener
Trener

I denne andre fasen må vi ta alle brukerdata fra datasettet vårt og "trene" OpenCV Recognizer. Dette gjøres direkte av en spesifikk OpenCV -funksjon. Resultatet blir en.yml -fil som blir lagret i en "trener/" - katalog.

Så la oss begynne å lage en underkatalog der vi skal lagre de opplærte dataene:

mkdir trener

Last ned det andre python -skriptet fra GitHub: 02_face_training.py

importer cv2

import numpy as np fra PIL import Bildeimport os # Sti for ansiktsbildedatabasesti = 'datasett' gjenkjenner = cv2.face. LBPHFaceRecognizer_create () detektor = cv2. CascadeClassifier ("haarcascade_frontalface_default.xml"); # funksjon for å få bildene og etikettdata def getImagesAndLabels (path): imagePaths = [os.path.join (path, f) for f in os.listdir (path)] 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]) ansikter = detector.detectMultiScale (img_numpy) for (x, y, w, h) i ansikter: faceSamples.append (img_numpy [y: y+h, x: x+w]) ids.append (id) return faceSamples, ids print ("\ n [INFO] Treningsflater. Det vil ta noen sekunder. Vent …") ansikter, ids = getImagesAndLabels (path) anerkjenner.trening (ansikter, np.array (ids)) # Lagre modellen i trainer/trainer.yml anerkjennere.skrive ('trainer/trainer.yml') # gjenkjenne. lagre () jobbet på Mac, men ikke på Pi # Skriv ut antall ansikter som er trent og avslutt programutskrift ("\ n [INFO] {0} ansikter trent. Avslutter program".format (len (np.unique (ids))))

Bekreft om du har PIL -biblioteket installert på Rpi. Hvis ikke, kjør kommandoen nedenfor i Terminal:

pip installer pute

Vi vil bruke LBPH (LOCAL BINARY PATTERNS HISTOGRAMS) som gjenkjenner, inkludert i OpenCV -pakken. Vi gjør dette på følgende linje:

gjenkjenner = cv2.face. LBPHFaceRecognizer_create ()

Funksjonen "getImagesAndLabels (path)", vil ta alle bildene i katalogen: "datasett/", og returnere 2 matriser: "Ids" og "ansikter". Med disse matrisene som input, vil vi "trene vår gjenkjenner":

anerkjenner.trening (ansikter, id -er)

Som et resultat vil en fil som heter "trainer.yml" bli lagret i trenermappen som tidligere ble opprettet av oss.

Det er det! Jeg inkluderte den siste utskriftserklæringen der jeg viste for bekreftelse, antall bruker ansikter vi har trent.

Hver gang du utfører fase 1, må fase 2 også kjøres

Trinn 7: Gjenkjenner

Gjenkjenner
Gjenkjenner
Gjenkjenner
Gjenkjenner

Nå nådde vi siste fase av prosjektet. Her vil vi fange et friskt ansikt på kameraet vårt, og hvis denne personen hadde fått ansiktet fanget og trent før, vil vår gjenkjenning lage en "forutsigelse" som returnerer ID og en indeks, vist hvor trygg gjenkjenneren er med denne kampen.

La oss laste ned 3. fase python -skriptet fra GitHub: 03_face_recognition.py.

importer cv2

import numpy as np import os identifierer = cv2.face. LBPHFaceRecognizer_create () anerkjennere.les ('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 videoopptakskamera i sanntid = cv2. VideoCapture (0) cam.set (3, 640) # set video widht cam.set (4, 480) # set video høyde # Definer min vindustørrelse å bli gjenkjent som et ansikt minW = 0,1*cam.get (3) minH = 0,1*cam.get (4) mens True: ret, img = cam.read () img = cv2.flip (img, -1) # Vend vertikalt grått = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansikter = faceCascade.detectMultiScale (grå, scaleFactor = 1.2, minNeighbors = 5, minSize = (int (minW), int (minH)),) for (x, y, w, h) i ansikter: cv2.rektangel (img, (x, y), (x+w, y+h), (0, 255, 0), 2) id, tillit = gjenkjenner.predikt (grå [y: y+h, x: x+w]) # Sjekk om tilliten er mindre 100 ==> "0" er perfekt match hvis (tillit <100): id = navn [id] tillit = "{0}% ".format (runde (100 - tillit)) else: id =" ukjent "tillit =" {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 (tillit), (x+5, y+h-5), font, 1, (255, 255, 0), 1) cv2.imshow ('kamera', img) k = cv2.waitKey (10) & 0xff # Trykk 'ESC' for å avslutte video hvis k == 27: pause # Gjør litt opprydding ("\ n [INFO] Avslutter program og opprydding") cam.release () cv2.destroyAllWindows ()

Vi inkluderer her en ny matrise, så vi vil vise "navn", i stedet for nummererte ID -er:

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

Så, for eksempel: Marcelo vil brukeren med id = 1; Paula: id = 2, etc.

Deretter vil vi oppdage et ansikt, det samme som vi gjorde før med haasCascade -klassifisereren. Etter å ha et påvist ansikt kan vi kalle den viktigste funksjonen i koden ovenfor:

id, tillit = gjenkjenner. forutsi (grå del av ansiktet)

Recognizer.predict (), tar som en parameter en fanget del av ansiktet som skal analyseres og returnerer den sannsynlige eieren, som angir ID og hvor stor tillit gjenkjenneren har i forhold til denne kampen.

Vær oppmerksom på at konfidensindeksen vil returnere "null" hvis den blir ansett som en perfekt match

Og til slutt, hvis gjenkjenneren kunne forutsi et ansikt, legger vi en tekst over bildet med den sannsynlige IDen og hvor mye er "sannsynligheten" i % at kampen er riktig ("sannsynlighet" = 100 - konfidensindeks). Hvis ikke, settes en "ukjent" etikett på ansiktet.

Nedenfor en-g.webp

Bilde
Bilde

På bildet ovenfor viser jeg noen tester utført med dette prosjektet, hvor jeg også har brukt bilder for å bekrefte om gjenkjenneren fungerer.

Trinn 8: Konklusjon

Konklusjon
Konklusjon

Som alltid håper jeg at dette prosjektet kan hjelpe andre å finne veien inn i den spennende elektronikkverdenen!

For detaljer og siste kode, vennligst besøk mitt GitHub-depot: OpenCV-Face-Recognition

For flere prosjekter, vennligst besøk bloggen min: MJRoBot.org

Nedenfor et glimt av en fremtidig opplæring, hvor vi skal utforske "automatisk ansiktsspor og andre metoder for ansiktsgjenkjenning":

Bilde
Bilde

Hilsener fra den sørlige verden!

Se deg i min neste instruerbare!

Takk skal du ha, Marcelo

Anbefalt: