webcam.py 3.45 KB
Newer Older
1
"""
Arne Gerdes's avatar
Arne Gerdes committed
2
Diese Klasse ist das Main-Modul. Es lädt das Modell aus models, zeigt ein Webcam-Bild,
Arne Gerdes's avatar
Arne Gerdes committed
3
erkennt das Gesicht und seine Emotionen und zeichnet ein Emoticon in das Bild.
4
"""
tihmels's avatar
tihmels committed
5
import argparse
6 7

import cv2
Arne Gerdes's avatar
Arne Gerdes committed
8
import numpy as np
9
from RingBuffer import RingBuffer
10
from WebcamVideoStream import WebcamVideoStream
11
from face_detect import extract_faces
12 13
from image_commons import nparray_as_image, draw_with_alpha

tihmels's avatar
tihmels committed
14 15
parser = argparse.ArgumentParser(description='ProjectMood Camplication')
parser.add_argument('-b', action='store', dest='buffer', default=10, type=int, help='size of ringbuffer')
Arne Gerdes's avatar
Arne Gerdes committed
16 17
parser.add_argument('-e', action='append', dest='emotions', default=['happy', 'neutral', 'sadness', 'surprise'],
                    help='declare emotions that should be detected')
tihmels's avatar
tihmels committed
18
parser.add_argument('-r', action='append', dest='resize', default=150, help='resize factor')
Arne Gerdes's avatar
Arne Gerdes committed
19 20
parser.add_argument('--model', action='store', dest='model', default='resources/models/detection_model.xml',
                    help='path to model')
tihmels's avatar
tihmels committed
21
arguments = parser.parse_args()
22

Arne Gerdes's avatar
Arne Gerdes committed
23

24 25
def _load_emoticons(emotions):
    """
26
     Lädt die Emoticons aus dem emojis Ordner.
Arne Gerdes's avatar
Arne Gerdes committed
27 28
    :param  emotions: Array von Emotionen.
    :return: Array von Emotions Grafiken.
29
    """
30
    return [nparray_as_image(cv2.imread('resources/emojis/%s.png' % emotion, -1), mode=None) for emotion in emotions]
31 32


33
def show_webcam_and_run(model, emoticons, window_size=(600, 600), window_name='Project Mood', update_time=1):
34
    """
Arne Gerdes's avatar
Arne Gerdes committed
35 36 37 38 39 40
    Zeigt ein Webcam-Bild, erkennt Gesichter und Emotionen in Echtzeit und zeichnet Emoticons neben die Gesichter.
    :param model: Trainiertes Model
    :param emoticons: Liste von Emoticons.
    :param window_size: Grösse des Webcam-Fensters.
    :param window_name: Name des Webcam-Fensters.
    :param update_time: Bildaktualisierungzeit.
41
    """
42
    cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
43 44
    width, height = window_size
    cv2.resizeWindow(window_name, width, height)
45

46
    vc = WebcamVideoStream().start()
47

Arne Gerdes's avatar
Arne Gerdes committed
48
    """
tihmels's avatar
tihmels committed
49
    Der RingBuffer speichert die letzten x Predictions
Arne Gerdes's avatar
Arne Gerdes committed
50
    """
tihmels's avatar
tihmels committed
51
    buffer = RingBuffer(arguments.buffer)
52

53
    frame = vc.read()
54

55
    while True:
tihmels's avatar
tihmels committed
56
        for normalized_face in extract_faces(frame, arguments.resize):
Arne Gerdes's avatar
Arne Gerdes committed
57
            prediction = model.predict(normalized_face)  # do prediction
58

Arne Gerdes's avatar
Arne Gerdes committed
59 60 61
            """
            Seichert die Predictions
            """
62
            buffer.append(prediction[0])
Arne Gerdes's avatar
Arne Gerdes committed
63 64

            """
65
            Holt die Einträge als Array
Arne Gerdes's avatar
Arne Gerdes committed
66
            """
67
            predictions = buffer.get()
Arne Gerdes's avatar
Arne Gerdes committed
68 69 70 71

            """
            Kein Eintrag im RingBuffer ist None 
            """
72
            if not (any(x is None for x in predictions)):
Arne Gerdes's avatar
Arne Gerdes committed
73 74 75
                """
                Vorkommen der Predictions zählen 
                """
76
                unique, counts = np.unique(predictions, return_counts=True)
Arne Gerdes's avatar
Arne Gerdes committed
77 78 79 80 81

                """
                Häufigster Wert wird dargestellt
                """
                image_to_draw = emoticons[unique[0]]
82
                draw_with_alpha(frame, image_to_draw, (40, 40, 200, 200))
83

84 85
        cv2.imshow(window_name, frame)
        frame = vc.read()
86 87 88
        key = cv2.waitKey(update_time)

        if key == 27:  # exit on ESC
89
            vc.stop()
90 91 92 93 94 95
            break

    cv2.destroyWindow(window_name)


if __name__ == '__main__':
tihmels's avatar
tihmels committed
96
    emotions = arguments.emotions
97 98 99
    emoticons = _load_emoticons(emotions)

    fisher_face = cv2.face.FisherFaceRecognizer_create()
Arne Gerdes's avatar
Arne Gerdes committed
100

101
    """Lädt das trainierte Model"""
tihmels's avatar
tihmels committed
102
    fisher_face.read(arguments.model)
103
    show_webcam_and_run(fisher_face, emoticons)