webcam.py 3.5 KB
Newer Older
tihmels's avatar
tihmels committed
1
import argparse
2
import os
3 4

import cv2
tihmels's avatar
tihmels committed
5
import cv2.face
Arne Gerdes's avatar
Arne Gerdes committed
6
import numpy as np
7

8
from RingBuffer import RingBuffer
9
from WebcamVideoStream import WebcamVideoStream
10
from face_detect import extract_faces
11
from image_commons import nparray_as_image, draw_with_alpha, draw_img
12

tihmels's avatar
tihmels committed
13 14 15
parser = argparse.ArgumentParser(description='ProjectMood Emotion Detection')
parser.add_argument('-b', '--buffer', action='store', dest='buffer', default=12, type=int, help='size of ringbuffer')
parser.add_argument('-m', '--model', action='store', dest='model', default='resources/models/detection_model.xml',
Arne Gerdes's avatar
Arne Gerdes committed
16
                    help='path to model')
tihmels's avatar
tihmels committed
17
arguments = parser.parse_args()
18

19

20 21
def _load_emoticons(emotions):
    """
22 23 24
    Load the emoticons from the emojis folder.
     : param emotions: emotions as an array.
     : return: Array of Emotions graphics.
25
    """
26 27
    return [nparray_as_image(cv2.imread('resources/emojis/{}.png'.format(emotion), -1), mode=None) for emotion in
            emotions]
28 29


tihmels's avatar
tihmels committed
30
def show_webcam_and_run(model, emoticons, window_size=(600, 600), window_name=parser.description, update_time=1):
31
    """
32 33 34 35 36 37
    Shows a webcam image, recognizes faces and emotions in real time and draws emoticons next to the faces.
     : param model: Trained Model
     : param emoticons: list of emoticons.
     : param window_size: Size of the webcam window.
     : param window_name: name of the webcam window.
     : param update_time: Image update time.
38
    """
39
    cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
40 41
    width, height = window_size
    cv2.resizeWindow(window_name, width, height)
42

43
    vc = WebcamVideoStream().start()
44

45
    # a random image from the dataset to determine the image format (important for Fisherface)
tihmels's avatar
tihmels committed
46 47 48
    random = cv2.imread('resources/img_data/dataset/{}/0.jpg'.format(emotions[0]))
    resizefactor = np.size(random, 0)

49
    # The RingBuffer stores the last x Predictions
tihmels's avatar
tihmels committed
50
    buffer = RingBuffer(arguments.buffer)
51

52
    frame = vc.read()
53

54
    while True:
tihmels's avatar
tihmels committed
55
        for normalized_face in extract_faces(frame, resizefactor):
56
            # prediction = model.predict(normalized_face)  # do prediction
57

58
            # Save the Predictions
59
            # buffer.append(prediction[0])
Arne Gerdes's avatar
Arne Gerdes committed
60

61
            # Get the entries as an array
62
            predictions = buffer.get()
Arne Gerdes's avatar
Arne Gerdes committed
63

64 65 66 67 68 69
            # Read the processed input image
            processed_image = nparray_as_image(normalized_face[:, :], mode='L')
            w, h = vc.size()
            # And print it to the frame
            draw_img(frame, processed_image, (w-300, h-300, 250, 250))

70
            # No entry in the ring buffer is None
71
            if not (any(x is None for x in predictions)):
72
                # Counting occurrences of predictions
73
                unique, counts = np.unique(predictions, return_counts=True)
Arne Gerdes's avatar
Arne Gerdes committed
74

75
                # Most frequent value is displayed
Arne Gerdes's avatar
Arne Gerdes committed
76
                image_to_draw = emoticons[unique[0]]
77
                draw_with_alpha(frame, image_to_draw, (40, 40, 200, 200))
78

79 80
        cv2.imshow(window_name, frame)
        frame = vc.read()
81 82
        key = cv2.waitKey(update_time)

83 84
        # exit on ESC
        if key == 27:
85
            vc.stop()
86 87 88 89 90 91
            break

    cv2.destroyWindow(window_name)


if __name__ == '__main__':
92
    # The emotions in the Dataset folder should also be loaded in the application
tihmels's avatar
tihmels committed
93 94
    _, emotions, _ = next(os.walk('resources/img_data/dataset'), (None, [], None))

95 96 97
    emoticons = _load_emoticons(emotions)

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

99
    # Load the trained model
tihmels's avatar
tihmels committed
100
    fisher_face.read(arguments.model)
101
    show_webcam_and_run(fisher_face, emoticons)