sorted_set_facedetector.py 4.71 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 22

parser = argparse.ArgumentParser(description='Sorted Set Face Creator Application')
23 24
parser.add_argument('--source', action='store', dest='img_source', default='resources/img_data/sorted_set/',
                    help='path to image source')
Arne Gerdes's avatar
Arne Gerdes committed
25 26
parser.add_argument('--dataset', action='store', dest='dataset', default='resources/img_data/dataset/',
                    help='path to dataset')
tihmels's avatar
tihmels committed
27
parser.add_argument('-r', action='store', dest='resize', default=150, type=int, help='resize factor')
Arne Gerdes's avatar
Arne Gerdes committed
28 29
parser.add_argument('-e', action='append', dest='emotions', default=['happy', 'neutral', 'surprise'],
                    help='declare emotions that should be processed')
30 31 32 33
parser.add_argument('-c', action='store', dest='scaleFactor', default=1.1, type=float,
                    help='scale factor - haar')
parser.add_argument('-n', action='store', dest='minNeighbors', default=6, type=int, help='min neighbors - haar')
parser.add_argument('-s', action='store', dest='minSize', default=40, type=int, help='min size - haar')
34
parser.add_argument('--email', action='store_true', help='activate email notifications')
35
arguments = parser.parse_args()
36 37 38 39 40 41 42 43 44 45
logging.debug(arguments)

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
46

47
if len(glob.glob(dataset_path + '*')) > 0:
48
    deleteDataset = input(
49
        'Im Dataset befinden sich Dateien. Durch diesen Vorgang werden die existierenden Daten gelöscht. Fortfahren (y/n): ')
50 51

    if deleteDataset == 'y':
52
        for file in glob.glob(dataset_path + '*'):
53 54 55
            shutil.rmtree(file)
    else:
        sys.exit()
56

tihmels's avatar
tihmels committed
57 58 59 60
totalFiles: int = 0
totalFaces: int = 0
undetected: list = []

61

62
def detect_faces(emotion):
63 64 65
    """
    Holt alle Dateien zu einer Emotion aus dem sorted_set
    """
66
    files = glob.glob(source_path + '{}/*'.format(emotion))
67 68 69 70

    global undetected
    global totalFaces
    global totalFiles
71

72
    logging.info("Found {} {} files".format(len(files), emotion))
73 74

    fileNumber = 0
75 76
    for f in files:
        frame = cv2.imread(f)  # Open image
77
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # Convert image to grayscale
78

79
        facefeatures = locate_faces(gray, scaleFactor, minNeighbors, (minSize, minSize))
tihmels's avatar
tihmels committed
80 81

        if facefeatures is '':
tihmels's avatar
tihmels committed
82
            logging.info('No face detected in ' + f)
83
            undetected.append(f)
84 85
            if len(undetected) % 200 == 0 and email:
                sendMail('Already ' + str(len(undetected)) + ' not detected faces', filepath=logfile)
86 87 88 89 90 91
        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:
92 93
                    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
94
                    if not success:
Arne Gerdes's avatar
Arne Gerdes committed
95
                        logging.error('Problem while writing file ' + f + ' occurred...')
96
                        if email:
Arne Gerdes's avatar
Arne Gerdes committed
97 98
                            sendMail('Problem while writing file',
                                     body=f + ' to ' + dataset_path + '{}/{}.jpg'.format(emotion, fileNumber))
99
                except:
100
                    logging.error('Some error with ' + f)
101
                    if email:
102
                        sendMail('Problem while writing file', body=f)
103
                    pass  # If error, pass file
104

tihmels's avatar
tihmels committed
105
        totalFiles += 1  # Increment image number
106
        fileNumber += 1
tihmels's avatar
tihmels committed
107

Arne Gerdes's avatar
Arne Gerdes committed
108

109
if email:
110
    sendMail('Facedetector started notification')
111

112
for emotion in emotions:
113

114 115
    if not os.path.exists(dataset_path + emotion):
        os.makedirs(dataset_path + emotion)
116

117 118
    detect_faces(emotion)  # Call functional

119 120
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
121

122
for f in undetected:
123 124
    logging.info(f)

125 126
if email:
    sendMail('Facedetector finished notification', filepath=logfile)