Innehållsförteckning:

Ansiktsigenkänning i realtid: ett projekt från början till slut: 8 steg (med bilder)
Ansiktsigenkänning i realtid: ett projekt från början till slut: 8 steg (med bilder)

Video: Ansiktsigenkänning i realtid: ett projekt från början till slut: 8 steg (med bilder)

Video: Ansiktsigenkänning i realtid: ett projekt från början till slut: 8 steg (med bilder)
Video: JAG BODDE 4 MÅNADER I THAILAND 2024, November
Anonim
Ansiktsigenkänning i realtid: ett projekt från början till slut
Ansiktsigenkänning i realtid: ett projekt från början till slut

Under min senaste handledning som utforskade OpenCV lärde vi oss AUTOMATIC VISION OBJECT TRACKING. Nu kommer vi att använda vår PiCam för att känna igen ansikten i realtid, som du kan se nedan:

Bild
Bild

Detta projekt gjordes med detta fantastiska "Open Source Computer Vision Library", OpenCV. I denna handledning kommer vi att fokusera på Raspberry Pi (alltså Raspbian som OS) och Python, men jag testade också koden på min Mac och det fungerar också bra. OpenCV har utformats för beräkningseffektivitet och med stort fokus på realtidsapplikationer. Så det är perfekt för ansiktsigenkänning i realtid med en kamera.

För att skapa ett komplett projekt om ansiktsigenkänning måste vi arbeta med tre mycket olika faser:

  1. Ansiktsigenkänning och datainsamling
  2. Träna igenkännaren
  3. Ansiktsigenkänning

Nedanstående blockdiagram återupptar dessa faser:

Bild
Bild

Steg 1: BoM - materialräkning

Huvuddelar:

  1. Raspberry Pi V3 - 32,00 US $
  2. 5 megapixlar 1080p sensor OV5647 minikamera videomodul - 13,00 US $

Steg 2: Installera OpenCV 3 -paketet

Installera OpenCV 3 -paketet
Installera OpenCV 3 -paketet

Jag använder en Raspberry Pi V3 uppdaterad till den senaste versionen av Raspbian (Stretch), så det bästa sättet att ha OpenCV installerat är att följa den utmärkta självstudien som utvecklats av Adrian Rosebrock: Raspbian Stretch: Installera OpenCV 3 + Python på din Raspberry Pi.

Jag försökte flera olika guider för att installera OpenCV på min Pi. Adrians handledning är den bästa. Jag råder dig att göra detsamma, följ hans riktlinje steg-för-steg.

När du har avslutat Adrians handledning bör du ha en virtuell OpenCV -miljö redo att köra våra experiment på din Pi.

Låt oss gå till vår virtuella miljö och bekräfta att OpenCV 3 är korrekt installerat.

Adrian rekommenderar att du kör kommandot "source" varje gång du öppnar en ny terminal för att säkerställa att dina systemvariabler har konfigurerats korrekt.

källa ~/.profile

Låt oss sedan gå in på vår virtuella miljö:

workon cv

Om du ser texten (cv) före din fråga, befinner du dig i cv: s virtuella miljö:

(cv) pi@hallon: ~ $Adrian uppmärksammar att cv Pythons virtuella miljö är helt oberoende och avskild från standard Python -versionen som ingår i nedladdningen av Raspbian Stretch. Så, alla Python-paket i den globala platspaketkatalogen kommer inte att vara tillgängliga för cv-virtuella miljön. På samma sätt kommer alla Python-paket som är installerade i platspaket för cv inte att vara tillgängliga för den globala installationen av Python

Skriv nu in din Python -tolk:

pytonorm

och bekräfta att du kör versionen 3.5 (eller högre)

Inuti tolken (">>>" visas), importera OpenCV -biblioteket:

importera cv2

Om inga felmeddelanden visas är OpenCV korrekt installerat PÅ DIN PYTHON VIRTUAL MILJÖ.

Du kan också kontrollera den installerade OpenCV -versionen:

cv2._ version_

3.3.0 ska visas (eller en överlägsen version som kan släppas i framtiden). Ovanstående Terminal PrintScreen visar de föregående stegen.

Steg 3: Testa din kamera

Testar din kamera
Testar din kamera

När du har installerat OpenCV i din RPi ska vi testa för att bekräfta att din kamera fungerar korrekt.

Jag antar att du redan har en PiCam installerad på din Raspberry Pi.

Ange Python -koden nedan på din IDE:

importera 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 (ram, -1) # Vänd kamera vertikalt grå = cv2.cvtColor (ram, cv2. COLOR_BGR2GRAY) cv2.imshow ('ram', ram) cv2.imshow ('grå', grå) k = cv2.waitKey (30) & 0xff om k == 27: # tryck 'ESC' för att avsluta break cap.release () cv2.destroyAllWindows ()

Ovanstående kod kommer att fånga videoströmmen som kommer att genereras av din PiCam och visa båda, i BGR -färg och gråläge.

Observera att jag roterade min kamera vertikalt på grund av hur den är monterad. Om det inte är ditt fall, kommentera eller ta bort kommandoraden "flip".

Du kan alternativt ladda ner koden från min GitHub: simpleCamTest.py

För att utföra, ange kommandot:

python simpleCamTest.py

För att avsluta programmet måste du trycka på tangenten [ESC] på tangentbordet.

Klicka med musen på videofönstret innan du trycker på [ESC]

Bilden ovan visar resultatet.

Vissa tillverkare hittade problem när de försökte öppna kameran (felmeddelanden "påstående misslyckades"). Det kan hända om kameran inte var aktiverad under OpenCv -installationen och kameradrivrutinerna inte installerades korrekt. För att korrigera, använd kommandot:

sudo modprobe bcm2835-v4l2

Du kan också lägga till bcm2835-v4l2 till den sista raden i filen /etc /modules så att drivrutinen laddas vid start.

För att veta mer om OpenCV kan du följa självstudien: loading -video-python-opencv-tutorial

Steg 4: Ansiktsigenkänning

Ansiktsigenkänning
Ansiktsigenkänning
Ansiktsigenkänning
Ansiktsigenkänning

Den mest grundläggande uppgiften för ansiktsigenkänning är naturligtvis "Ansiktsigenkänning". Innan någonting måste du "fånga" ett ansikte (fas 1) för att känna igen det, jämfört med ett nytt ansikte som fångas i framtiden (fas 3).

Det vanligaste sättet att upptäcka ett ansikte (eller några föremål) är att använda "Haar Cascade classifier"

Objektdetektering med hjälp av Haar-funktionsbaserade kaskadklassificerare är en effektiv objektdetekteringsmetod som föreslogs av Paul Viola och Michael Jones i deras uppsats "Rapid Object Detection using a Boosted Cascade of Simple Features" 2001. Det är en maskininlärningsbaserad metod där en kaskadfunktionen tränas från många positiva och negativa bilder. Det används sedan för att upptäcka objekt i andra bilder.

Här kommer vi att arbeta med ansiktsigenkänning. Initialt behöver algoritmen många positiva bilder (bilder av ansikten) och negativa bilder (bilder utan ansikten) för att träna klassificeraren. Då måste vi extrahera funktioner från det. Den goda nyheten är att OpenCV levereras med både en tränare och en detektor. Om du vill träna din egen klassificerare för något objekt som bil, flygplan etc. kan du använda OpenCV för att skapa ett. Dess fullständiga detaljer ges här: Cascade Classifier Training.

Om du inte vill skapa din egen klassificerare innehåller OpenCV redan många förutbildade klassificerare för ansikte, ögon, leende etc. Dessa XML-filer kan laddas ner från haarcascades-katalogen.

Nog med teori, låt oss skapa en ansiktsdetektor med OpenCV!

Ladda ner filen: faceDetection.py från min GitHub.

importera 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öjd medan True: ret, img = cap.read () img = cv2.flip (img, -1) grå = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansikten = faceCascade.detectMultiScale (grå, scaleFactor = 1.2, minNeighbors = 5, minSize = (20, 20)) för (x, y, w, h) i ansikten: 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 om k == 27: # tryck på 'ESC' för att avsluta break cap.release () cv2.destroyAllWindows ()

Tro det eller ej, ovanstående få kodrader är allt du behöver för att upptäcka ett ansikte med Python och OpenCV.

När du jämför med den senaste koden som används för att testa kameran kommer du att inse att få delar har lagts till i den. Notera raden nedan:

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

Detta är raden som laddar "klassificeraren" (som måste finnas i en katalog som heter "Kaskader/", under din projektkatalog).

Sedan kommer vi att ställa in vår kamera och inuti slingan, ladda vår inmatningsvideo i gråskala -läge (samma som vi såg tidigare).

Nu måste vi kalla vår klassificeringsfunktion och skicka några mycket viktiga parametrar som skalfaktor, antal grannar och minsta storlek på det detekterade ansiktet.

ansikten = faceCascade.detectMultiScale (grå, scaleFactor = 1,2, minNeighbors = 5, minSize = (20, 20))

Var,

  • grå är inmatnings gråskala bilden.
  • scaleFactor är parametern som anger hur mycket bildstorleken minskar vid varje bildskala. Den används för att skapa skalpyramiden.
  • minNeighbors är en parameter som anger hur många grannar varje kandidatrektangel ska ha för att behålla den. Ett högre tal ger lägre falska positiva.
  • minSize är den minsta rektangelstorleken som ska betraktas som ett ansikte.

Funktionen upptäcker ansikten på bilden. Därefter måste vi "markera" ansiktena i bilden med exempelvis en blå rektangel. Detta görs med den här delen av koden:

för (x, y, w, h) i ansikten:

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]

Om ansikten hittas returnerar det positionerna för detekterade ansiktena som en rektangel med vänster uppåt hörnet (x, y) och med "w" som dess bredd och "h" som dess höjd ==> (x, y, w, h). Se bilden ovan.

När vi fått dessa platser kan vi skapa en "ROI" (ritad rektangel) för ansiktet och presentera resultatet med imshow () -funktionen.

Kör ovanstående python -skript på din python -miljö med Rpi -terminalen:

python faceDetection.py

Resultatet:

Bild
Bild

Du kan också inkludera klassificerare för "ögondetektering" eller till och med "leendekänning". I dessa fall kommer du att inkludera klassificeringsfunktionen och rektangelritningen inuti ansiktsöglan, eftersom det inte vore meningsfullt att upptäcka ett öga eller ett leende utanför ett ansikte.

Observera att på en Pi, med flera klassificerare vid samma kod, kommer processen att bromsa, när denna detektionsmetod (HaarCascades) använder en stor mängd beräkningskraft. På ett skrivbord är det lättare att köra det.

På min GitHub hittar du andra exempel:

faceEyeDetection.py

faceSmileDetection.py

faceSmileEyeDetection.py

Och i bilden ovan kan du se resultatet.

Du kan också följa nedanstående handledning för att bättre förstå ansiktsigenkänning:

Haar Cascade Object Detection Face & Eye OpenCV Python -handledning

Steg 5: Datainsamling

Datainsamling
Datainsamling
Datainsamling
Datainsamling

Först och främst måste jag tacka Ramiz Raja för hans fantastiska arbete med ansiktsigenkänning på foton:

ANSIKTSERKÄNNING MED OPENCV OCH PYTHON: EN BEGÄNNARGUIDE

och även Anirban Kar, som utvecklade en mycket omfattande handledning med hjälp av video:

ANSIKTSKÄNNANDE - 3 delar

Jag rekommenderar verkligen att du tar en titt på båda handledningarna.

Med det sagt, låt oss börja den första fasen av vårt projekt. Vad vi kommer att göra här, börjar från sista steget (Ansiktsigenkänning), vi kommer helt enkelt att skapa en datauppsättning, där vi för varje id kommer att lagra en grupp foton i grått med den del som användes för ansiktsdetektering.

Skapa först en katalog där du utvecklar ditt projekt, till exempel FacialRecognitionProject:

mkdir FacialRecognitionProject

I den här katalogen, förutom de 3 python -skript som vi kommer att skapa för vårt projekt, måste vi ha sparat ansiktsklassificeraren på den. Du kan ladda ner den från min GitHub: haarcascade_frontalface_default.xml

Skapa sedan en underkatalog där vi kommer att lagra våra ansiktsprover och ge den namnet "dataset":

mkdir dataset

Och ladda ner koden från min GitHub: 01_face_dataset.py

importera 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') # För varje person, ange ett numeriskt ansikts -ID face_id = input ('\ n ange användar -id slut tryck ==>') utskrift ("\ n [INFO] Initierar ansiktsinspelning. Titta på kameran och vänta …") # Initiera individuellt antal provtagningar för ansikte = 0 medan (True): ret, img = cam.read () img = cv2.flip (img, -1) # vänd videobild vertikalt grå = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansikten = face_detector.detectMultiScale (grå, 1,3, 5) för (x, y, w, h) i ansikten: cv2.rektangel (img, (x, y), (x+w, y+h), (255, 0, 0), 2) count + = 1 # Spara den tagna bilden i datamängden mappen cv2.imwrite ("dataset/User." + str (face_id) + '.' + str (count) + ".jpg", grå [y: y + h, x: x+w]) cv2.imshow ('image', img) k = cv2.waitKey (100) & 0xff # Tryck på 'ESC' för att lämna videon om k == 27: bryt elif count> = 30: # Ta 30 ansikteprov och stoppa videopausen # Gör ab it of cleanup -utskrift ("\ n [INFO] Avsluta program och saneringssaker") cam.release () cv2.destroyAllWindows ()

Koden är mycket lik den kod som vi såg för ansiktsigenkänning. Det vi lade till var ett "inmatningskommando" för att fånga ett användar -ID, som ska vara ett heltal (1, 2, 3, etc)

face_id = input ('\ n ange användar -ID slut tryck ==>')

Och för var och en av de fångade ramarna bör vi spara den som en fil i en "dataset" -katalog:

cv2.imwrite ("dataset/användare." + str (face_id) + '.' + str (count) + ".jpg", grå [y: y + h, x: x + w])

Observera att för att spara ovanstående fil måste du ha importerat biblioteket "os". Varje fils namn följer strukturen:

User.face_id.count.jpg

Till exempel, för en användare med ett face_id = 1, kommer den fjärde exempelfilen på dataset/ katalog att vara ungefär så här:

Användare.1.4.jpg

som visas på bilden ovan från min Pi. På min kod fångar jag 30 prover från varje id. Du kan ändra det på den sista "elif". Antalet prover används för att bryta slingan där ansiktsproven fångas.

Kör Python -skriptet och fånga några ID: er. Du måste köra skriptet varje gång du vill samla en ny användare (eller ändra foton för en som redan finns).

Steg 6: Tränare

Tränare
Tränare

I den andra fasen måste vi ta all användardata från vår dataset och "träna" OpenCV Recognizer. Detta görs direkt av en specifik OpenCV -funktion. Resultatet blir en.yml -fil som sparas i en katalog "tränare/".

Så, låt oss börja skapa en underkatalog där vi kommer att lagra utbildade data:

mkdir tränare

Ladda ner från mitt GitHub det andra python -skriptet: 02_face_training.py

importera cv2

importera numpy som np från PIL import Bildimport os # Sökväg för ansiktsbilddatabas sökväg = 'dataset' igenkänare = cv2.face. LBPHFaceRecognizer_create () detektor = cv2. CascadeClassifier ("haarcascade_frontalface_default.xml"); # funktion för att hämta bilderna och märka data def getImagesAndLabels (sökväg): imagePaths = [os.path.join (sökväg, f) för f i os.listdir (sökväg)] faceSamples = ids = för imagePath i imagePaths: PIL_img = Image.open (imagePath).convert ('L') # konvertera den till gråskala img_numpy = np.array (PIL_img, 'uint8') id = int (os.path.split (imagePath) [-1]. split (".") [1]) ansikten = detector.detectMultiScale (img_numpy) för (x, y, w, h) i ansikten: faceSamples.append (img_numpy [y: y+h, x: x+w]) ids.append (id) return faceSamples, ids print ("\ n [INFO] Träningsytor. Det tar några sekunder. Vänta …") ansikten, ids = getImagesAndLabels (sökväg) identifierer.train (ansikten, np.array (ids)) # Spara modellen i tränare/trainer.yml igenkännare.skriv ('trainer/trainer.yml') # igenkännare.spara () fungerade på Mac, men inte på Pi # Skriv ut antalet utbildade ansikten och avsluta programutskrift ("\ n [INFO] {0} utbildade ansikten. Avslutar program".format (len (np.unique (ids))))

Bekräfta om du har PIL -biblioteket installerat på din Rpi. Om inte, kör kommandot nedan i Terminal:

pip installera kudden

Vi kommer att använda som en igenkänare, LBPH (LOCAL BINARY PATTERNS HISTOGRAMS) Face Recognizer, som ingår i OpenCV -paketet. Vi gör detta på följande rad:

identifierare = cv2.face. LBPHFaceRecognizer_create ()

Funktionen "getImagesAndLabels (sökväg)" tar alla foton i katalogen: "dataset/" och returnerar 2 matriser: "Id" och "ansikten". Med dessa matriser som ingång kommer vi att "träna vår igenkännare":

identifierare.train (ansikten, id)

Som ett resultat sparas en fil med namnet "trainer.yml" i tränarkatalogen som tidigare skapades av oss.

Det är allt! Jag inkluderade det senaste utskriftsutdraget där jag visade för bekräftelse, antalet användares ansikten vi har tränat.

Varje gång du utför fas 1 måste fas 2 också köras

Steg 7: Recognizer

Recognizer
Recognizer
Recognizer
Recognizer

Nu nådde vi den sista fasen av vårt projekt. Här kommer vi att fånga ett nytt ansikte på vår kamera och om den här personen hade fått sitt ansikte fångat och tränat tidigare kommer vår igenkännare att göra en "förutsägelse" som returnerar sitt id och ett index, visat hur säker igenkännaren är med denna match.

Låt oss ladda ner python -skriptet från tredje fasen från mitt GitHub: 03_face_recognition.py.

importera cv2

importera numpy som np importera os igenkänare = cv2.face. LBPHFaceRecognizer_create () igenkänna.läs ('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 '] # Initiera och starta videoinspelning i realtid cam = cv2. VideoCapture (0) cam.set (3, 640) # ställ in video widht cam.set (4, 480) # ställ in videohöjd # Definiera min fönsterstorlek att kännas igen som ansikte minW = 0,1*cam.get (3) minH = 0,1*cam.get (4) medan True: ret, img = cam.read () img = cv2.flip (img, -1) # Vänd vertikalt grått = cv2.cvtColor (img, cv2. COLOR_BGR2GRAY) ansikten = faceCascade.detectMultiScale (grå, scaleFactor = 1,2, minNeighbors = 5, minSize = (int (minW), int (minH)),) för (x, y, w, h) i ansikten: cv2.rektangel (img, (x, y), (x+w, y+h), (0, 255, 0), 2) id, förtroende = identifierare.predict (grå [y: y+h, x: x+w]) # Kontrollera om förtroendet är mindre än dem 100 ==> "0" är perfekt matchning om (konfidens <100): id = namn [id] förtroende = "{0}% ".format (runda (100 - konfidens)) else: id =" okänt "förtroende =" {0}%". format (runda (100 - konf idence)) cv2.putText (img, str (id), (x+5, y-5), font, 1, (255, 255, 255), 2) cv2.putText (img, str (konfidens), (x+5, y+h-5), font, 1, (255, 255, 0), 1) cv2.imshow ('kamera', img) k = cv2.waitKey (10) & 0xff # Tryck på 'ESC' för att avsluta video om k == 27: break # Gör lite rengöringsutskrift ("\ n [INFO] Avsluta program och sanering") cam.release () cv2.destroyAllWindows ()

Vi inkluderar här en ny array, så vi kommer att visa "namn", istället för numrerade id: er:

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

Så, till exempel: Marcelo kommer användaren med id = 1; Paula: id = 2, etc.

Därefter kommer vi att upptäcka ett ansikte, samma som vi gjorde tidigare med haasCascade -klassificeraren. Med ett upptäckt ansikte kan vi kalla den viktigaste funktionen i koden ovan:

id, förtroende = identifierare. förutsägelse (grå del av ansiktet)

Recognizer.predict (), tar som en parameter en fångad del av ansiktet som ska analyseras och returnerar sin troliga ägare, vilket anger dess id och hur mycket förtroende igenkännaren har för denna matchning.

Observera att konfidensindex kommer att returnera "noll" om det kommer att anses vara en perfekt matchning

Och slutligen, om igenkännaren kunde förutsäga ett ansikte, lägger vi en text över bilden med det troliga id och hur mycket är "sannolikheten" i % att matchningen är korrekt ("sannolikhet" = 100 - konfidensindex). Om inte, sätts en "okänd" etikett på ansiktet.

Nedan en-g.webp

Bild
Bild

På bilden ovan visar jag några tester som gjorts med detta projekt, där jag också har använt foton för att verifiera om identifieraren fungerar.

Steg 8: Slutsats

Slutsats
Slutsats

Som alltid hoppas jag att detta projekt kan hjälpa andra att hitta in i den spännande världen av elektronik!

För mer information och slutkod, besök min GitHub-förråd: OpenCV-Face-Recognition

För fler projekt, besök min blogg: MJRoBot.org

Nedan en glimt av en framtida handledning, där vi kommer att utforska "automatiskt ansiktsspår och andra metoder för ansiktsigenkänning":

Bild
Bild

Hälsningar från södra världen!

Vi ses i min nästa instruerbara!

Tack, Marcelo

Rekommenderad: