process_model.py 4.62 KB
Newer Older
Arne Gerdes's avatar
Arne Gerdes committed
1
2
3
"""
Diese Klasse macht das Training des Models möglich
"""
4
import argparse
Arne Gerdes's avatar
Arne Gerdes committed
5

Arne Gerdes's avatar
Arne Gerdes committed
6
7
8
9
import cv2
import glob
import random
import numpy as np
tihmels's avatar
tihmels committed
10
import sys
tihmels's avatar
tihmels committed
11
import logging
Arne Gerdes's avatar
Arne Gerdes committed
12

13
14
15
16
from email_service import sendMail

logfile = 'logs/process_model.log'

Arne Gerdes's avatar
Arne Gerdes committed
17
18
19
"""
Erstellt und gibt das Log-File aus 
"""
20
logging.basicConfig(level=logging.NOTSET, format='%(asctime)s %(levelname)-8s %(message)s',
tihmels's avatar
tihmels committed
21
                    datefmt='%m-%d %H:%M',
22
                    filename=logfile)
23

Arne Gerdes's avatar
Arne Gerdes committed
24
"""
25
Argument Parser erlaubt Parameter für die Verarbeitung anzugeben.
Arne Gerdes's avatar
Arne Gerdes committed
26
"""
Arne Gerdes's avatar
Arne Gerdes committed
27

28
29
parser = argparse.ArgumentParser(description='Process Model Application')
parser.add_argument('--dataset', action='store', dest='dataset', default='resources/img_data/dataset/', help='path to dataset')
30
parser.add_argument('-i', action='store', dest='iterations', type=int, default=30, help='number of iterations')
tihmels's avatar
tihmels committed
31
parser.add_argument('-e', action='append', dest='emotions', default=['happy', 'neutral', 'sadness', 'surprise'], help='declare emotions that should be processed')
32
parser.add_argument('-p', action='append', dest='properties', help='pre-processing steps for logging')
tihmels's avatar
tihmels committed
33
parser.add_argument('--test', action='store_true', help='prevent writing new model to classifier')
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
parser.add_argument('--csv', action='store_true', help='activate csv processing')
parser.add_argument('--email', action='store_true', help='activate email notifications')
arguments = parser.parse_args()
logging.debug(arguments)

dataset_path = arguments.dataset
iterations = arguments.iterations
emotions = arguments.emotions
properties = arguments.properties
csv = arguments.csv
email = arguments.email
test = arguments.test

"""
Liest Input Parameter 
"""
logging.info('Fisherface training started')
51

52
53
if email:
    sendMail('Fisherface training started')
Arne Gerdes's avatar
Arne Gerdes committed
54

55
56
57
58
59
60
def _get_faces_from_emotion(emotion):
    """
    Holt alle Dateien zu einer Emotion aus dem Dataset, mischt sie und teilt sie in ein Trainings- und Prognoseset.
    :param emotion: Die Emotion
    :return: training, prediction
    """
61
    files = glob.glob(dataset_path + '{}/*'.format(emotion))
Arne Gerdes's avatar
Arne Gerdes committed
62
    random.shuffle(files)
Arne Gerdes's avatar
Arne Gerdes committed
63
64
65
66
67
68
69

    """
    Mischt das Dataset in Trainings- und Vergleichsbilder im Verhältnis 80 zu 20 
    """
    training = files[:int(len(files) * 0.8)]
    prediction = files[-int(len(files) * 0.2):]

Arne Gerdes's avatar
Arne Gerdes committed
70
71
    return training, prediction

Arne Gerdes's avatar
Arne Gerdes committed
72

73
74
75
76
77
78
79
80
def image_preprocessing(image):
    """
    Preprocessing der Dateien
    :param item: Bild
    :return:
    """
    img = cv2.imread(image)  # open image
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # convert to grayscale
tihmels's avatar
tihmels committed
81
82
83
    clahe = cv2.createCLAHE(2.0, (8,8))
    norm = clahe.apply(gray)
    return norm
Arne Gerdes's avatar
Arne Gerdes committed
84

Arne Gerdes's avatar
Arne Gerdes committed
85

Arne Gerdes's avatar
Arne Gerdes committed
86
87
88
89
90
91
def make_sets():
    training_data = []
    training_labels = []
    prediction_data = []
    prediction_labels = []
    for emotion in emotions:
92
        training, prediction = _get_faces_from_emotion(emotion)
Arne Gerdes's avatar
Arne Gerdes committed
93
94
        # Append data to training and prediction list, and generate labels 0-7
        for item in training:
tihmels's avatar
tihmels committed
95
96
            img = image_preprocessing(item)
            training_data.append(img)  # append image array to training data list
Arne Gerdes's avatar
Arne Gerdes committed
97
98
99
            training_labels.append(emotions.index(emotion))

        for item in prediction:  # repeat above process for prediction set
tihmels's avatar
tihmels committed
100
101
            img = image_preprocessing(item)
            prediction_data.append(img)
Arne Gerdes's avatar
Arne Gerdes committed
102
103
104
105
            prediction_labels.append(emotions.index(emotion))

    return training_data, training_labels, prediction_data, prediction_labels

Arne Gerdes's avatar
Arne Gerdes committed
106

Arne Gerdes's avatar
Arne Gerdes committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
def run_recognizer():
    training_data, training_labels, prediction_data, prediction_labels = make_sets()

    fishface.train(training_data, np.asarray(training_labels))

    cnt = 0
    correct = 0
    incorrect = 0
    for image in prediction_data:
        pred, conf = fishface.predict(image)
        if pred == prediction_labels[cnt]:
            correct += 1
            cnt += 1
        else:
            incorrect += 1
            cnt += 1
    return ((100 * correct) / (correct + incorrect))

Arne Gerdes's avatar
Arne Gerdes committed
125
126
127
"""
Emotions Liste 
"""
tihmels's avatar
tihmels committed
128
fishface = cv2.face.FisherFaceRecognizer_create()
Arne Gerdes's avatar
Arne Gerdes committed
129
metascore = []
tihmels's avatar
tihmels committed
130

131
for i in range(1, iterations+1):
Arne Gerdes's avatar
Arne Gerdes committed
132
    correct = run_recognizer()
133
    logging.info("{} : {}%".format(i, int(correct)))
Arne Gerdes's avatar
Arne Gerdes committed
134
    metascore.append(correct)
135

136
137
138
139
140
141
142
143
144
145
146
147
148
    if i % (int(iterations/4)) == 0 and email:
        sendMail(str(i) + ' iterations done', body='up-to-date average: {}%'.format(np.mean(metascore)))

if csv:
    file = open("resources/csv/{}.csv".format('_'.join(properties).lower()), "w")
    for entry in metascore:
        file.write("{}\n".format(int(entry)))

    file.close()

logging.info("Fisherface training finished - {}% average\n".format(np.mean(metascore)))

if not test:
tihmels's avatar
tihmels committed
149
    fishface.write('resources/models/detection_model.xml')
Arne Gerdes's avatar
Arne Gerdes committed
150

151
152
if email:
    sendMail('Fisherface training finished')