File size: 2,312 Bytes
91c8e31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eb7cd31
 
91c8e31
eb7cd31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from deepface import DeepFace
import numpy as np
from PIL import Image, ExifTags

# used to raise custom exceptions
class ImageProcessingError(Exception):
    pass

# used to ensure upright photo orientation for face detection
def check_image_rotation(image_path):
    try:
        image = Image.open(image_path)
        for orientation in ExifTags.TAGS.keys():
            if ExifTags.TAGS[orientation] == 'Orientation':
                break
        exif = image._getexif()
        if exif is not None:
            if orientation in exif:
                if exif[orientation] == 3:
                    image = image.rotate(180, expand=True)
                elif exif[orientation] == 6:
                    image = image.rotate(270, expand=True)
                elif exif[orientation] == 8:
                    image = image.rotate(90, expand=True)
        return image
    except (AttributeError, KeyError, IndexError):
        # If the orientation tag is not found or any other error occurs, return the original image
        return Image.open(image_path)

# used to process photo through deepface emotion model
def process_photo(file_name):
    backends = ['opencv', 'mtcnn', 'retinaface', 'mediapipe', 'ssd']
    attempt = 0

    image = check_image_rotation(file_name)
    image_data = np.array(image)

    while attempt < len(backends):
        try:
            predictions = DeepFace.analyze(image_data, actions=['emotion'], detector_backend=backends[attempt])
            if len(predictions) > 1:
                faces = [(face, face['region']['w'] * face['region']['h']) for face in predictions]
                new_predictions = sorted(faces, key=lambda x: x[1], reverse=True)[0][0]
                emotion_dict = new_predictions['emotion']
                return emotion_dict
            return predictions['emotion']
        except Exception as e:
            if attempt == len(backends) - 1:
                error_message = f"Failed to analyze image after attempting all detector backends available. Please upload a new image."
                raise ImageProcessingError(error_message)
            else:
                # log the error message for each failed backend here:
                print(f"Retrying with backend `{backends[attempt+1]}` due to error: {str(e)}")
                attempt += 1