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

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
12

13 14 15 16
from email_service import sendMail

logfile = 'logs/process_model.log'

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

24
"""
25
Argument Parser erlaubt Parameter für die Verarbeitung anzugeben.
26
"""
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')
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))
62
    random.shuffle(files)
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):]

70 71
    return training, prediction

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
84

85

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)
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
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)
102 103 104 105
            prediction_labels.append(emotions.index(emotion))

    return training_data, training_labels, prediction_data, prediction_labels

106

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))

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

131
for i in range(1, iterations+1):
132
    correct = run_recognizer()
133
    logging.info("{} : {}%".format(i, int(correct)))
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')
150

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