Source code for profile_photo.utils.create_headshot

from __future__ import annotations

from os.path import splitext

import cv2 as cv
import numpy as np

from .aws.rekognition_models import DetectFacesResp, DetectLabelsResp
from .aws.rekognition_utils import best_fit_coordinates, show_image
from .img_orient import get_oriented_im_bytes, get_im_orientation
from ..models import ProfilePhoto


_DEFAULT_FILE_EXT = '.jpg'


[docs]def rotate_im_and_crop(fp: str, faces: DetectFacesResp, labels: DetectLabelsResp | None, file_ext: str | None = None, im_bytes: bytes = None, debug: bool = False, ) -> ProfilePhoto: # Get primary face in the photo (might need to be tweaked?) face = faces.get_face() # Get file extension (.jpg etc.) if not file_ext: file_ext = splitext(fp)[1] if fp else _DEFAULT_FILE_EXT # Get Image Orientation _, is_rotated, orientation = get_im_orientation(im_bytes) # Correct Image Orientation (If Needed) - Rotate Image if is_rotated: im_bytes = get_oriented_im_bytes(file_ext, im_bytes, orientation)[0] # Read in image data as OpenCV Image img_as_np = np.frombuffer(im_bytes, dtype=np.uint8) im = cv.imdecode(img_as_np, cv.IMREAD_COLOR) # Get bounding box for the Person in the photo person_box = labels.get_person_box(face) # Get X/Y coordinates for cropping coords = best_fit_coordinates(im, face.bounding_box, person_box) # Crop the Photo # crop_img = img[y:y+h, x:x+w] cropped_im = im[coords.y1:coords.y2, coords.x1:coords.x2] # Show cropped image (if debug is enabled) if debug: show_image('Result', cropped_im) cv.waitKey(0) # Convert the cropped photo to bytes final_im_bytes: bytes = cv.imencode(file_ext, cropped_im)[1].tobytes() return ProfilePhoto( fp, final_im_bytes, is_rotated, orientation, faces, labels, im_bytes, )