process_model.py 5.19 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
import glob
tihmels's avatar
tihmels committed
6
import logging
Arne Gerdes's avatar
Arne Gerdes committed
7
import random
Arne Gerdes's avatar
Arne Gerdes committed
8

Arne Gerdes's avatar
Arne Gerdes committed
9 10
import cv2
import numpy as np
11 12
import sys

13 14 15 16
from email_service import sendMail

logfile = 'logs/process_model.log'

17
# Erstellt und konfiguriert den Logger
18
logging.basicConfig(level=logging.NOTSET, format='%(asctime)s %(levelname)-8s %(message)s',
tihmels's avatar
tihmels committed
19
                    datefmt='%m-%d %H:%M',
20
                    filename=logfile)
21

22
# Argument Parser erlaubt Programmparameter anzugeben
23
parser = argparse.ArgumentParser(description='Process Model Application')
tihmels's avatar
tihmels committed
24 25 26 27 28 29 30 31
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')
parser.add_argument('-d', '--dataset', action='store', dest='dataset', default='resources/img_data/dataset/',
Arne Gerdes's avatar
Arne Gerdes committed
32
                    help='path to dataset')
33 34
parser.add_argument('-i' '--iterations', action='store', dest='iterations', type=int, default=30,
                    help='number of iterations')
tihmels's avatar
tihmels committed
35
parser.add_argument('-p', '--properties', nargs='+', dest='properties', help='pre-processing steps for logging')
36 37 38
parser.add_argument('-t', '--test', action='store_true', dest='test', help='prevent writing new model to classifier')
parser.add_argument('-c', '--csv', action='store_true', dest='csv', help='activate csv output')
parser.add_argument('-x', '--email', action='store_true', dest='email', help='activate email notifications')
39 40 41
arguments = parser.parse_args()
logging.debug(arguments)

42 43 44
if not arguments.emotions:
    print('No emotions declared')
    sys.exit()
45 46

logging.info('Fisherface training started')
47

48
if arguments.email:
49
    sendMail('Fisherface training started')
Arne Gerdes's avatar
Arne Gerdes committed
50

51 52 53 54 55 56
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
    """
57
    files = glob.glob(arguments.dataset + '{}/*'.format(emotion))
Arne Gerdes's avatar
Arne Gerdes committed
58
    random.shuffle(files)
Arne Gerdes's avatar
Arne Gerdes committed
59 60 61 62 63 64 65

    """
    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
66 67
    return training, prediction

Arne Gerdes's avatar
Arne Gerdes committed
68

69 70 71 72 73 74 75 76
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
Arne Gerdes's avatar
Arne Gerdes committed
77
    clahe = cv2.createCLAHE(2.0, (8, 8))
tihmels's avatar
tihmels committed
78 79
    norm = clahe.apply(gray)
    return norm
Arne Gerdes's avatar
Arne Gerdes committed
80

Arne Gerdes's avatar
Arne Gerdes committed
81

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

        for item in prediction:  # repeat above process for prediction set
tihmels's avatar
tihmels committed
96 97
            img = image_preprocessing(item)
            prediction_data.append(img)
98
            prediction_labels.append(arguments.emotions.index(emotion))
Arne Gerdes's avatar
Arne Gerdes committed
99 100 101

    return training_data, training_labels, prediction_data, prediction_labels

Arne Gerdes's avatar
Arne Gerdes committed
102

Arne Gerdes's avatar
Arne Gerdes committed
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
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
121

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

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

tihmels's avatar
nichts  
tihmels committed
133
    if arguments.email and i % (int(arguments.iterations / 4)) == 0:
134 135
        sendMail(str(i) + ' iterations done', body='up-to-date average: {}%'.format(np.mean(metascore)))

136 137
if arguments.csv:
    file = open("resources/csv/{}.csv".format('_'.join(arguments.properties).lower()), "w")
138 139 140 141 142 143 144
    for entry in metascore:
        file.write("{}\n".format(int(entry)))

    file.close()

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

145
if not arguments.test:
tihmels's avatar
tihmels committed
146
    fishface.write('resources/models/detection_model.xml')
Arne Gerdes's avatar
Arne Gerdes committed
147

148
if arguments.email:
149
    sendMail('Fisherface training finished')