sorted_set_facedetector.py 5.46 KB
Newer Older
Arne Gerdes's avatar
Arne Gerdes committed
1
import argparse
Arne Gerdes's avatar
Arne Gerdes committed
2
import glob
3
import logging
Arne Gerdes's avatar
Arne Gerdes committed
4
import os
5
6
7
import shutil
import sys

Arne Gerdes's avatar
Arne Gerdes committed
8
import cv2
9
from email_service import sendMail
tihmels's avatar
tihmels committed
10
from face_detect import locate_faces
Arne Gerdes's avatar
Arne Gerdes committed
11

12
13
14
logfile = 'logs/sorted_set_facedetector.log'

logging.basicConfig(level=logging.NOTSET, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
15
                    datefmt='%m-%d %H:%M',
16
                    filename=logfile,
17
                    filemode='w')
Arne Gerdes's avatar
Arne Gerdes committed
18
"""
19
Argument Parser erlaubt Parameter für die Verarbeitung anzugeben.
Arne Gerdes's avatar
Arne Gerdes committed
20
"""
21

tihmels's avatar
tihmels committed
22
23
24
25
26
27
28
29
30
parser = argparse.ArgumentParser(description='Dataset Preprocessor')
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('-s', '--source', action='store', dest='img_source', default='resources/img_data/sorted_set/',
31
                    help='path to image source')
tihmels's avatar
tihmels committed
32
parser.add_argument('-d', '--dataset', action='store', dest='dataset', default='resources/img_data/dataset/',
Arne Gerdes's avatar
Arne Gerdes committed
33
                    help='path to dataset')
tihmels's avatar
tihmels committed
34
35
36
37
38
39
parser.add_argument('-r', '--resize', action='store', dest='resize', default=250, type=int, help='resize factor')
parser.add_argument('-c', '--scale', action='store', dest='scaleFactor', default=1.1, type=float,
                    help='scale factor (haar)')
parser.add_argument('-n', '--minneighbors', action='store', dest='minNeighbors', default=6, type=int, help='min neighbors (haar)')
parser.add_argument('-m', '--minsize', action='store', dest='minSize', default=50, type=int, help='min size (haar)')
parser.add_argument('-x', '--email', action='store_true', help='activate email notifications')
40
arguments = parser.parse_args()
41
42
logging.debug(arguments)

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

47
48
49
50
51
52
53
54
source_path = arguments.img_source
dataset_path = arguments.dataset
resizeFactor = arguments.resize
emotions = arguments.emotions
scaleFactor = arguments.scaleFactor
minNeighbors = arguments.minNeighbors
minSize = arguments.minSize
email = arguments.email
55

tihmels's avatar
tihmels committed
56
57
if len(os.listdir(dataset_path)) > 0:
    delete_data = input(
58
        'Im Dataset befinden sich Dateien. Durch diesen Vorgang werden die existierenden Daten gelöscht. Fortfahren (y/n): ')
59

tihmels's avatar
tihmels committed
60
61
62
63
    if delete_data == 'y':
        dir = [f for f in os.listdir(dataset_path) if os.path.isdir(os.path.join(dataset_path, f))]
        for d in dir:
            shutil.rmtree(os.path.join(dataset_path, d))
64
    else:
tihmels's avatar
tihmels committed
65
        print('process aborted by user')
66
        sys.exit()
Arne Gerdes's avatar
Arne Gerdes committed
67

tihmels's avatar
tihmels committed
68
69
70
71
totalFiles: int = 0
totalFaces: int = 0
undetected: list = []

Arne Gerdes's avatar
Arne Gerdes committed
72
def detect_faces(emotion):
Arne Gerdes's avatar
Arne Gerdes committed
73
74
75
    """
    Holt alle Dateien zu einer Emotion aus dem sorted_set
    """
76
    files = glob.glob(source_path + '{}/*'.format(emotion))
77
78
79
80

    global undetected
    global totalFaces
    global totalFiles
Arne Gerdes's avatar
Arne Gerdes committed
81

82
    logging.info("Found {} {} files".format(len(files), emotion))
83
84

    fileNumber = 0
Arne Gerdes's avatar
Arne Gerdes committed
85
86
    for f in files:
        frame = cv2.imread(f)  # Open image
87
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # Convert image to grayscale
Arne Gerdes's avatar
Arne Gerdes committed
88

89
        facefeatures = locate_faces(gray, scaleFactor, minNeighbors, (minSize, minSize))
tihmels's avatar
tihmels committed
90
91

        if facefeatures is '':
tihmels's avatar
tihmels committed
92
            logging.info('No face detected in ' + f)
93
            undetected.append(f)
94
95
            if len(undetected) % 200 == 0 and email:
                sendMail('Already ' + str(len(undetected)) + ' not detected faces', filepath=logfile)
96
97
98
99
100
101
        else:
            # Cut and save face
            for (x, y, w, h) in facefeatures:  # get coordinates and size of rectangle containing face
                totalFaces += 1
                gray = gray[y:y + h, x:x + w]  # Cut the frame to size
                try:
102
103
                    out = cv2.resize(gray, (resizeFactor, resizeFactor))  # Resize face so all images have same size
                    success = cv2.imwrite(dataset_path + '{}/{}.jpg'.format(emotion, fileNumber), out)  # Write image
104
                    if not success:
Arne Gerdes's avatar
Arne Gerdes committed
105
                        logging.error('Problem while writing file ' + f + ' occurred...')
106
                        if email:
Arne Gerdes's avatar
Arne Gerdes committed
107
108
                            sendMail('Problem while writing file',
                                     body=f + ' to ' + dataset_path + '{}/{}.jpg'.format(emotion, fileNumber))
109
                except:
110
                    logging.error('Some error with ' + f)
111
                    if email:
112
                        sendMail('Problem while writing file', body=f)
113
                    pass  # If error, pass file
114

tihmels's avatar
tihmels committed
115
        totalFiles += 1  # Increment image number
116
        fileNumber += 1
tihmels's avatar
tihmels committed
117

Arne Gerdes's avatar
Arne Gerdes committed
118

119
if email:
120
    sendMail('Facedetector started notification')
121

122
for emotion in emotions:
Arne Gerdes's avatar
Arne Gerdes committed
123

124
125
    if not os.path.exists(dataset_path + emotion):
        os.makedirs(dataset_path + emotion)
Arne Gerdes's avatar
Arne Gerdes committed
126

127
128
    detect_faces(emotion)  # Call functional

129
130
logging.info('{} faces in {} files found'.format(totalFaces, totalFiles))
logging.info('In {} files no face could be detected'.format(totalFiles - totalFaces))
tihmels's avatar
tihmels committed
131

132
for f in undetected:
133
134
    logging.info(f)

135
136
if email:
    sendMail('Facedetector finished notification', filepath=logfile)