BlogLinuxPythonRaspberry

Gesichtserkennung in Python Part II

Gesichtserkennung Python Part 2

Im ersten Gesichtserkennung Tutorial habe ich an einem existierenden Beispiel gezeigt, wie diese einzurichten ist. Ich habe das Script nun um folgende Funktionen erweitert. Die erste Erweiterung ermöglicht das Erkennen von mehreren Personen. Die Zweite begrüßt erkannte Personen mit einer persönlichen Sprachnachricht.

Für diese Erweiterung habe ich die Dateistruktur leicht verändert:

 

im Ordner faces liegen Bilder von bekannten Personen. Die gleichnamige Sprachdatei liegt dabei unter welcomemessage. Der Code selber liegt im Root Ordner face_recognition.

Schaut man sich die Unterschiede zwischen dem Code in Part I und Part II an, so bemerkt man, dass es nur kleine Änderungen sind. Ich habe die Funktion WelcomePeople hinzugefügt. WelcomePeople kümmert sich um die Sprachnachricht und lädt jene, falls zu der erkannten Person eine existiert.

def WelcomePeople(name):
  #this functions is trying to load the music file in welcome/.
  #if it cannot find a file a exception raises
  #if that file exist it is starting a voice message for that recognized person

  music = name + ".wav"
  print(music)
  pygame.mixer.init()
  try:
      pygame.mixer.music.load("welcome/" + music)
      pygame.mixer.music.play()
  except:
    print("could not find welcome file")

 

Ebenfalls habe ich die Variablen zum größtenteils als Listen initialisiert. In diesem Snippet werden alle bekannten Personen von faces/ geladen. Von diesem wird dann ein Stempel erzeugt, der zu dem späteren Vergleich dazu gezogen wird.

#is loading all images in faces/ and create a stamp
try:
    for faces,i in zip(os.listdir("faces"),range(len(os.listdir("faces")))):
        known_faces.append("faces/"+faces)
        image.append(face_recognition.load_image_file("faces/" + faces))
        known_face_encoding.append(face_recognition.face_encodings(image[i])[0])
except:
  print("could not find known pictures")
  exit()

 

Im letzten Part vergleichen wir den Stempel von den Personen, die bei der Kamera eingefangen wurden und denen, die wir als bekannte Personen deklariert haben. Die For Schleife habe ich um der Variable i und (range(len(known_faces))) erweitert. Damit sollen die richtigen Daten aus den Listen known_face_encoding und known_faces hinzugezogen werden.

for face, i in zip(os.listdir("faces"), range(len(known_faces))):

 

Ebenfalls wurde ein Timestamp hinzugefügt. Dieser soll sicherstellen, dass eine Person nur alle 10 Minuten begrüßt wird. Die Bedingung überprüft die Existenz einer bereits begrüßten Person und nimmt diese 10 Minuten als Referenzwert für die nächste Begrüßung.

                #check when the person has been welcomed already. If that person has been welcomed it must wait 10 minutes to hear the message again
                if not last_welcome:
                    last_welcome[face.split(".")[0]] = datetime.datetime.now()
                    WelcomePeople(face.split(".")[0])
                elif face.split(".")[0] not in last_welcome:
                    last_welcome[face.split(".")[0]] = datetime.datetime.now()
                    WelcomePeople(face.split(".")[0])
                else:
                    if (last_welcome[face.split(".")[0]] + datetime.timedelta(seconds=10)) >= datetime.datetime.now():
                        last_welcome[face.split(".")[0]] = datetime.datetime.now()
                        WelcomePeople(face.split(".")[0])
                    else:
                        print("already greeted")

 

Hier noch einmal der komplette Block über den ich gerade gesprochen habe. Last_welcome wurde als Dictionary deklariert, damit ich eine vereinfachte Zuordnung vom Timestamp und erkannte Personen habe. Eine Liste wäre hier komplizierte da ich nur nummerische Zahlen als Key verwenden könnte.

# Loop over each face found in the frame to see if it's someone we know.
for face_encoding in face_encodings:
    
    for face, i in zip(os.listdir("faces"), range(len(known_faces))):
    	# See if the face is a match for the known face(s)
        if face_recognition.compare_faces([known_face_encoding[i]], face_encoding,0.6)[0]:
        	#print found face all upper case
            print("<found: ".upper() + known_faces[i].upper() + ">")
            #check when the person has been welcomed already. If that person has been welcomed it must wait 10 minutes to hear the message again
            if not last_welcome:
                last_welcome[face.split(".")[0]] = datetime.datetime.now()
                WelcomePeople(face.split(".")[0])
            elif face.split(".")[0] not in last_welcome:
                last_welcome[face.split(".")[0]] = datetime.datetime.now()
                WelcomePeople(face.split(".")[0])
            else:
                if (last_welcome[face.split(".")[0]] + datetime.timedelta(seconds=10)) >= datetime.datetime.now():
                    last_welcome[face.split(".")[0]] = datetime.datetime.now()
                    WelcomePeople(face.split(".")[0])
                else:
                    print("already greeted")

 

Damit hätten wir dann den Code im Schnelldurchgang erklärt.

Zum Schluss der komplette Code der Gesichtserkennung:

# This is a demo of running face recognition on a Raspberry Pi.
# This program will print out the names of anyone it recognizes to the console.

# To run this, you need a Raspberry Pi 2 (or greater) with face_recognition and
# the picamera[array] module installed.
# You can follow this installation instructions to get your RPi set up:
# https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65

try:
  import face_recognition
  import picamera
  import numpy as np
  import os
  import pygame
  import datetime
except:
  print("failed to load module")
  exit()


# Initialize some variables
face_locations			= []
face_encodings 			= []
image 					= []
known_face_encoding 	= []
known_faces				= []
last_welcome			= {}

def WelcomePeople(name):
  #this functions is trying to load the music file in welcome/.
  #if it cannot find a file a exception raise
  #if that file exist it is starting a voice message for that recognized person

  music = name + ".wav"
  print(music)
  pygame.mixer.init()
  try:
      pygame.mixer.music.load("welcome/" + music)
      pygame.mixer.music.play()
  except:
    print("could not find welcome file")

# Get a reference to the Raspberry Pi camera.
# If this fails, make sure you have a camera connected to the RPi and that you
# enabled your camera in raspi-config and rebooted first.
try:
    camera = picamera.PiCamera()
    camera.resolution = (320, 240)
    output = np.empty((240, 320, 3), dtype=np.uint8)	
except:
  print("something went wrong while initialize camera")
  exit()



# Load pictures and learn how to recognize it.
print("Loading known face image(s)")

#is loading all images in faces/ and create a stamp
try:
    for faces,i in zip(os.listdir("faces"),range(len(os.listdir("faces")))):
        known_faces.append("faces/"+faces)
        image.append(face_recognition.load_image_file("faces/" + faces))
        known_face_encoding.append(face_recognition.face_encodings(image[i])[0])
except:
  print("could not find known pictures")
  exit()


while True:
    print("Capturing image.")
    # Grab a single frame of video from the RPi camera as a numpy array
    camera.capture(output, format="rgb")

    # Find all the faces and face encodings in the current frame of video
    face_locations = face_recognition.face_locations(output)
    print("Found {} faces in image.".format(len(face_locations)))
    face_encodings = face_recognition.face_encodings(output, face_locations)

    # Loop over each face found in the frame to see if it's someone we know.
    for face_encoding in face_encodings:
        
        for face, i in zip(os.listdir("faces"), range(len(known_faces))):
        	# See if the face is a match for the known face(s)
            if face_recognition.compare_faces([known_face_encoding[i]], face_encoding,0.6)[0]:
            	#print found face all upper case
                print("<found: ".upper() + known_faces[i].upper() + ">")
                #check when the person has been welcomed already. If that person has been welcomed it must wait 10 minutes to hear the message again
                if not last_welcome:
                    last_welcome[face.split(".")[0]] = datetime.datetime.now()
                    WelcomePeople(face.split(".")[0])
                elif face.split(".")[0] not in last_welcome:
                    last_welcome[face.split(".")[0]] = datetime.datetime.now()
                    WelcomePeople(face.split(".")[0])
                else:
                    if (last_welcome[face.split(".")[0]] + datetime.timedelta(seconds=10)) >= datetime.datetime.now():
                        last_welcome[face.split(".")[0]] = datetime.datetime.now()
                        WelcomePeople(face.split(".")[0])
                    else:
                        print("already greeted")

 

 

 

7 Gedanken zu „Gesichtserkennung in Python Part II

  1. Hallo Stevie,

    ich bin echt begeistert von deinem Tutorial für die Gesichtserkennung. Ich habe genau nach so etwas gesucht und durch deine Hilfe, bin ich sehr schnell (fast) zum Ziel gekommen. Ich habe vor im Eingangsbereich die Gäste begrüßen zu lassen. Leider kommt es bei dem Code in Part II zu einer Fehlermeldung. Wenn er ein Gesicht erkennt und im Anschluss ein zweites Gesicht erkannt wird, kommt es zu einem Abbruch.

    Traceback (most recent call last):
    File „/home/pi/face_recognition/Gesichtserkennung.py“, line 89, in
    if not last_welcome or (last_welcome[face.split(„.“)[0]] + datetime.timedelta(seconds=10)) >= datetime.datetime.now():
    KeyError: ’steffi‘

    Ich hoffe, dass du mir helfen kannst.

    Viele Grüße aus dem hohen Norden.

    Michael

    1. Hallo Michael,

      schön zuhören, dass dir mein Tutorial gefällt.
      Ein KeyError besagt, das er in einem Dic, List, etc den Key nicht finden kann. In deinem Fall wäre es der von „steffi“.
      Funktioniert die erste Erkennung den soweit? Falls ja hab ich den Fehler wahrscheinlich schon gefunden.
      Dadurch das if not last_welcome False zurückgibt, checkt er auf den Wert last_welcome[„steffi“], den es zurzeit ja noch nicht gibt.
      Eine Umstrukturierung der Bedingung ist notwendig, damit er auch die 2 nicht erkannte Person begrüßt.

      if not last_welcome:
      last_welcome[face.split(„.“)[0]] = datetime.datetime.now()
      WelcomePeople(face.split(„.“)[0])
      elif face.split(„.“)[0] not in last_welcome:
      last_welcome[face.split(„.“)[0]] = datetime.datetime.now()
      WelcomePeople(face.split(„.“)[0])
      else:
      if (last_welcome[face.split(„.“)[0]] + datetime.timedelta(seconds=10)) >= datetime.datetime.now():
      last_welcome[face.split(„.“)[0]] = datetime.datetime.now()
      WelcomePeople(face.split(„.“)[0])
      else:
      print(„already greeted“)

      Hab ich soweit jetzt nicht getestet, aber damit könnte es gehen.

      Viel Glück.

      mfg
      stevie

      1. Hi Stevie,

        vielen Dank für deine schnelle Antwort. Ich hab den Code eingefügt. Ich bin mir nicht ganz sicher, ob ich diesen richtig eingesetzt habe, aber leider erhalte ich immer eine Fehlermeldung in der elif Zeile.

        for face_encoding in face_encodings:
        for face, i in zip(os.listdir(„faces“), range(len(known_faces))):
        # See if the face is a match for the known face(s)
        if face_recognition.compare_faces([known_face_encoding[i]], face_encoding,0.6)[0]:
        #print found face all upper case
        print(„“)

        if not last_welcome:
        last_welcome[face.split(„.“)[0]] = datetime.datetime.now()
        WelcomePeople(face.split(„.“)[0])

        elif face.split(„.“)[0] not in last_welcome:
        last_welcome[face.split(„.“)[0]] = datetime.datetime.now()
        WelcomePeople(face.split(„.“)[0])

        else:
        if (last_welcome[face.split(„.“)[0]] + datetime.timedelta(seconds=10)) >= datetime.datetime.now():
        last_welcome[face.split(„.“)[0]] = datetime.datetime.now()
        WelcomePeople(face.split(„.“)[0])
        else:
        print(„already greeted“)

        Die Fehlermeldung lautet:
        Traceback (most recent call last):
        File „/home/pi/face_recognition/Gesichtserkennung.py“, line 92
        elif face.split(„.“)[0] not in last_welcome:
        ^
        SyntaxError: invalid syntax

        Die Meldung kommt direkt, wenn ich das Script starte.
        Dass ich die Anführungszeichen in Hochkommas geändert habe, ist doch korrekt oder?
        Zu deiner Frage zum ersten Code: Ja, die erste Person wird immer erkannt, egal mit welcher Person ich starte.

        Viele Grüße
        Michael

        1. Hallo Michael,

          ich habe den Code im Tutorial nun mit den Änderungen angepasst. Ich hoffe diesmal hilft es dir weiter. Ich konnte es aber leider noch nicht testen, ob die 2. Person nun erfolgreich begrüßt wird.

          mfg
          stevie

          1. Hallo Stevie,

            es funktioniert. Vielen Dank. Dann werde ich mich mal an das Einpflegen von Gesichtern machen. 🙂

            Vielen Dank nochmal

            Michael

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.