Kurzbeschreibung

Entwicklung von Gesichtsausdrücke für einen humanoiden Roboter (Poppy).

Dokumentation

Heutezutage sind Roboter Humanoider und intelligenter geworden.Viele Beispiele wie Cozmo oder Sawyer von Rethink Robotics waren sehr hilfreich für meine Recherche am Anfang meines Ingernieurspraxis.

Das Bild zeigt die verschiedenen Emotionen von Cozmo:

Arbeitsplan:

In erster Stelle habe ich angefangen mit der Entwicklung von Mini Programme,die ein Fenster erstellen und mit Hilfe von Formen Augen und Augenbrauen erstellen um die Merkmale des Gesichtes zu zeichnen:

Kontrol-Parameter:

Dann um die Augenoefnung ,Augenfarbe, Gesichtsfarbe flexibler zu erstellen habe ich dafür Parameter benutzt.

Erstens habe ich eine Klasse Eyes erstellt (wird in der End-Version nicht mehr benutzt ),die der Benutzer Eingabe kontrolliert (z.B Augenoeffnung zwischen 0 und 100) und die Werte speichert um die danach an der Klasse Drawer zu übergeben.

Die Klasse Drawer hat die Aufgabe aus den Parameter die in gelesen wurden ein Fenster mit den gelesenen Höhe und Breite zu erstellen und ein Canvas mit der augewaehlten Farbe .In der Mitte des Fensters(wird mit Faktoren wie 1/8*höhe etc. berechnet) werden Ovale und Bögen gezeichnet.

Welcome Window:

Danach um die Eingabe der Parameter einfacher für den Benutzer zu machen und nicht nur durch die Konsole habe ich ein MainFenster erstellt, das die Wahl der Parameter ermöglicht dafür wurden Buttons für die Emotionen Slider  für die Wahl der Höhe , Breite und Augenoefnung ( Als default Werte werden 500, 500, 50 ausgewählt).

 Ein Entry-Feld für die Eingabe der Gesichtsfarbe.

Ein Knopf für die Wahl der Augenfarbe (wenn man auf dem Knopf drückt kommt ein  Fenster mit ein Farbmixer)

Wenn man auf dem Knopf (Create Face ) drückt wird ein Fenster mit den ausgewählten Parameter generiert  

Emotionen erkennen:

Noch ein Knopf (Emotion Recognition)war dazu das um ein zweites Python Programm aus zu führen (emotions.py)

In einem zweiten Teil habe ich mich mit dem Thema Emotion Recognition beschäftigt und das Blog von Paulvangent war dafür sehr hilfreich .

Landmarks:

Um Emotionen zu erkennen kann die Analyse von Facial Landmarks und dazu ein Programm,das abhängig von den verschiedenen Landmarks Emotionen erkennen , die Aufgabe Erledigen.

                                                                          

Fig. 1: A face with 68 detected landmarks. White dots represent the outer lips.   

Fig. 2: Sadness, represented by a depression of the corners of the mouth.( ARTNATOMY by Victoria Contreras Flores (Spain 2005).)


Dataset:

Auch mit Hilfe von Datasets (z.B Cohn-Kanade Dataset)kann man sein Programm Trainieren um die gleiche Merkmale(Augenoefnung ,Lachen, Augenbrauen Bewegung) wie in den Photos vom Dataset wieder zu erkennen wenn ein Gesicht auf dem Video Stream detektiert wird.

In dem Programm Emotions.py kann man das Programm in Update Mode ausführen(das heißt weiter Gesichter zum Dataset hinzufügen) oder in normaler Mode, in dem ein Fenster mit dem Video Stream vom Webcam gezeigt wird und mit Hilfe des FisherFaceRecognizer und die Methode Recognize_Emotion die Emotion erkennt wird.


  1. Erstellen des Datasets oder Laden des Datasets:


    def make_sets(emotions): #creates the dataset in update mode
        training_data = []
        training_labels = []
    
        for emotion in emotions:
            training = training = glob.glob("dataset\\%s\\*" %emotion)
            for item in training:
                image = cv2.imread(item) 
                gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 
                training_data.append(gray)
                training_labels.append(emotions.index(emotion))
    
        return training_data, training_labels

    Erweiterung des Datasets

    in Emotions.py Zeile 17:Argument update ändern
    parser.add_argument("-update", help="Call to grab new images and update the model accordingly",
    action="store_true") -> Program im normal Mode ausführen
    parser.add_argument("update", help="Call to grab new images and update the model accordingly",
    action="store_true") -> Program in Update Mode (weitere Bilder zum Dataset hinzufuegen) ausführen




def save_face(emotion): #save the images in the dataset folder in update mode
    print(
        "\n\nplease look " + emotion + " when the timer expires and keep the expression stable until instructed otherwise.")
    for i in range(0, 5):  # Timer to give you time to read what emotion to express
        print(5 - i)
        time.sleep(1)
    while len(facedict.keys()) < 6:  # Grab 15 images for each emotion
        detect_face()
    for x in facedict.keys():  # save contents of dictionary to files
        cv2.imwrite("dataset\\%s\\%s.jpg" % (emotion, len(glob.glob("dataset\\%s\\*" % emotion))), facedict[x])
    facedict.clear()  # clear dictionary so that the next emotion can be stored


2.Trainieren des Datasets:  Einfach mit Benutzung von"cv2.train"

Auch es besteht die Möglichkeit zwischen 3 Face Recognizers zu waehlen in unserem Fall wird der FisherFaceRecognizer benutzt

  • EigenFaces – cv2.face.EigenFaceRecognizer_create()
  • FisherFaces – cv2.face.FisherFaceRecognizer_create()
  • Local Binary Patterns Histograms (LBPH) – cv2.face.LBPHFaceRecognizer_create()

    def run_recognizer(emotions): #runs the fisherfacerecognizer to be trained
        training_data, training_labels = make_sets(emotions)
        print("training fisher face classifier")
        print("size of training set is: " + str(len(training_labels)) + " images")
        fishface.train(training_data, np.asarray(training_labels))

       



3. Launch Video Stream:

video_capture = cv2.VideoCapture(0)
def detect_face(): #detect faces on the webcam
    clahe_image = grab_webcamframe()
    res,frame = video_capture.read()
    face = facecascade.detectMultiScale(clahe_image, scaleFactor=1.1, minNeighbors=15, minSize=(10, 10),
                                        flags=cv2.CASCADE_SCALE_IMAGE)
    cv2.imshow("webcam", frame)  # Display frame
    if cv2.waitKey(1) & 0xFF == ord('q'):
        pass
    if len(face) == 1:
        faceslice = crop_face(clahe_image, face)
        return faceslice
    else:
        print("no/multiple faces detected, passing over frame")

 4.Recognize_emotion: mit Hilfe von "cv2.predict" werden 2 Listen  predictions und confidence  erstellt und in denen wird die Emotion geschaetzt

def recognize_emotion(): #method to recognize the emotion displayed on the webcam
    predictions = []
    confidence = []
    for x in facedict.keys():
        pred, conf = fishface.predict(facedict[x])
        cv2.imwrite("images\\%s.jpg" % x, facedict[x])
        predictions.append(pred)
        confidence.append(conf)

Dieses Teil hängt von vielen Faktoren ab z.B( Licht ,Person ...),das das Vergleichen ist abhängig vom Dataset





Notwendige Software:

  • Das Projekt war in Python 3.6 programmiert also kompatibel mit jeder 3.X Python Version.
  • Für die GUI wird die Tkinter Library,die einfach mit "pip install tkinter" runtergeladen werden kann.
  • Für das  Emotion Recognition Teil braucht man OpenCV ein Tool für Computer Vision .
  • Die Dlib Library war mit OpenCv benutzt um das FisherFaceRecognizer zu trainieren.

  • Auch face_recognition 

  • Mit Hilfe der Zeile "fenster.attributes("-fullscreen,1")" kann die GUI auf das Display:4inch HDMI LCD,800x480,IPS gerzeigt.
  • Als IDE habe ich IDLE/Pycharm benutzt.
  • Keine Stichwörter