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