webcam.py 4.23 KB
Newer Older
tihmels's avatar
tihmels committed
1
import argparse
2
import os
Arne Gerdes's avatar
Arne Gerdes committed
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
Arne Gerdes's avatar
Arne Gerdes committed
12

tihmels's avatar
tihmels committed
13
parser = argparse.ArgumentParser(description='ProjectMood Emotion Detection')
tihmels's avatar
tihmels committed
14
15
16
17
18
19
20
parser.add_argument('-0', action='append_const', dest='emotions', const='neutral', help='neutral')
parser.add_argument('-1', action='append_const', dest='emotions', const='happy', help='happy')
parser.add_argument('-2', action='append_const', dest='emotions', const='sadness', help='sadness')
parser.add_argument('-3', action='append_const', dest='emotions', const='surprise', help='surprise')
parser.add_argument('-4', action='append_const', dest='emotions', const='fear', help='fear')
parser.add_argument('-5', action='append_const', dest='emotions', const='disgust', help='disgust')
parser.add_argument('-6', action='append_const', dest='emotions', const='anger', help='anger')
tihmels's avatar
tihmels committed
21
22
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
23
                    help='path to model')
tihmels's avatar
tihmels committed
24
parser.add_argument('-r', '--resize', action='store', type=int, dest='resizefactor')
tihmels's avatar
tihmels committed
25
arguments = parser.parse_args()
Arne Gerdes's avatar
Arne Gerdes committed
26

27

Arne Gerdes's avatar
Arne Gerdes committed
28
29
def _load_emoticons(emotions):
    """
30
31
32
    Load the emoticons from the emojis folder.
     : param emotions: emotions as an array.
     : return: Array of Emotions graphics.
Arne Gerdes's avatar
Arne Gerdes committed
33
    """
34
35
    return [nparray_as_image(cv2.imread('resources/emojis/{}.png'.format(emotion), -1), mode=None) for emotion in
            emotions]
Arne Gerdes's avatar
Arne Gerdes committed
36

tihmels's avatar
tihmels committed
37
def show_webcam_and_run(model, emoticons, window_size=(600, 600), window_name=parser.description, update_time=1):
Arne Gerdes's avatar
Arne Gerdes committed
38
    """
39
40
41
42
43
44
    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.
Arne Gerdes's avatar
Arne Gerdes committed
45
    """
46
    cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
47
48
    width, height = window_size
    cv2.resizeWindow(window_name, width, height)
Arne Gerdes's avatar
Arne Gerdes committed
49

50
    vc = WebcamVideoStream().start()
51

tihmels's avatar
tihmels committed
52
53
54
55
56
57
    if not arguments.resizefactor:
        # a random image from the dataset to determine the image format (important for Fisherface)
        random = cv2.imread('resources/img_data/dataset/{}/0.jpg'.format(arguments.emotions[0]))
        resizefactor = np.size(random, 0)
    else:
        resizefactor = arguments.resizefactor
tihmels's avatar
tihmels committed
58

59
    # The RingBuffer stores the last x Predictions
tihmels's avatar
tihmels committed
60
    buffer = RingBuffer(arguments.buffer)
61

62
    frame = vc.read()
Arne Gerdes's avatar
Arne Gerdes committed
63

64
    while True:
tihmels's avatar
tihmels committed
65
        for normalized_face in extract_faces(frame, resizefactor):
66
            prediction = model.predict(normalized_face)  # do prediction
67

68
            # Save the Predictions
69
            buffer.append(prediction[0])
Arne Gerdes's avatar
Arne Gerdes committed
70

71
            # Get the entries as an array
72
            predictions = buffer.get()
Arne Gerdes's avatar
Arne Gerdes committed
73

tihmels's avatar
tihmels committed
74
75
            print(predictions)

76
77
78
79
80
81
            # 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))

82
            # No entry in the ring buffer is None
83
            if not (any(x is None for x in predictions)):
84
                # Counting occurrences of predictions
85
                unique, counts = np.unique(predictions, return_counts=True)
Arne Gerdes's avatar
Arne Gerdes committed
86

87
                # Most frequent value is displayed
Arne Gerdes's avatar
Arne Gerdes committed
88
                image_to_draw = emoticons[unique[0]]
89
                draw_with_alpha(frame, image_to_draw, (40, 40, 200, 200))
Arne Gerdes's avatar
Arne Gerdes committed
90

91
92
        cv2.imshow(window_name, frame)
        frame = vc.read()
Arne Gerdes's avatar
Arne Gerdes committed
93
94
        key = cv2.waitKey(update_time)

95
96
        # exit on ESC
        if key == 27:
97
            vc.stop()
Arne Gerdes's avatar
Arne Gerdes committed
98
99
100
101
102
103
            break

    cv2.destroyWindow(window_name)


if __name__ == '__main__':
tihmels's avatar
tihmels committed
104
    emoticons = _load_emoticons(arguments.emotions)
Arne Gerdes's avatar
Arne Gerdes committed
105
106

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

108
    # Load the trained model
tihmels's avatar
tihmels committed
109
    fisher_face.read(arguments.model)
110
    show_webcam_and_run(fisher_face, emoticons)