sorted_set_facedetector.py 5.56 KB
Newer Older
Arne Gerdes's avatar
Arne Gerdes committed
1
import argparse
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
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')
18
"""
19
Argument Parser erlaubt Parameter für die Verarbeitung anzugeben.
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
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,
tihmels's avatar
tihmels committed
36 37 38 39
                    help='scale factor (ViolaJ)')
parser.add_argument('-n', '--minneighbors', action='store', dest='minNeighbors', default=6, type=int, help='min neighbors (ViolaJ)')
parser.add_argument('-m', '--minsize', action='store', dest='minSize', default=50, type=int, help='min size (ViolaJ)')
parser.add_argument('-p', '--prefix', action='store', dest='prefix', default='', help='prefix for files')
tihmels's avatar
tihmels committed
40
parser.add_argument('-x', '--email', action='store_true', help='activate email notifications')
41
arguments = parser.parse_args()
42 43
logging.debug(arguments)

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

48 49 50 51 52 53 54 55
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
56

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

tihmels's avatar
tihmels committed
61 62 63 64
    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))
65
    else:
tihmels's avatar
tihmels committed
66
        print('process aborted by user')
67
        sys.exit()
68

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

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

    global undetected
    global totalFaces
    global totalFiles
82

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

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

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

        if facefeatures is '':
tihmels's avatar
tihmels committed
93
            logging.info('No face detected in ' + f)
94
            undetected.append(f)
95
            if len(undetected) % 200 == 0 and email:
tihmels's avatar
tihmels committed
96
                sendMail('Already ' + str(len(undetected)) + ' undetected faces', filepath=logfile)
97 98 99 100 101 102
        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:
tihmels's avatar
tihmels committed
103
                    save_file = dataset_path + '{}/{}{}.jpg'.format(emotion, arguments.prefix, file_name_number)
104
                    out = cv2.resize(gray, (resizeFactor, resizeFactor))  # Resize face so all images have same size
tihmels's avatar
tihmels committed
105
                    success = cv2.imwrite(save_file, out)  # Write image
106
                    if not success:
tihmels's avatar
tihmels committed
107
                        logging.error('Problem while writing file ' + str(f) + ' occurred...')
108
                        if email:
Arne Gerdes's avatar
Arne Gerdes committed
109
                            sendMail('Problem while writing file',
tihmels's avatar
tihmels committed
110
                                     body=str(f) + ' to ' + save_file)
111
                except:
112
                    logging.error('Some error with ' + f)
113
                    if email:
tihmels's avatar
tihmels committed
114
                        sendMail('Some error occured', body=f, filepath=logfile)
115
                    pass  # If error, pass file
116

tihmels's avatar
tihmels committed
117
        totalFiles += 1  # Increment image number
tihmels's avatar
tihmels committed
118
        file_name_number += 1
119

120
for emotion in emotions:
121

122 123
    if not os.path.exists(dataset_path + emotion):
        os.makedirs(dataset_path + emotion)
124

125 126
    detect_faces(emotion)  # Call functional

127 128
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
129

130
for f in undetected:
131 132
    logging.info(f)

133 134
if email:
    sendMail('Facedetector finished notification', filepath=logfile)