|
""" |
|
File: face_utils.py |
|
Author: Elena Ryumina and Dmitry Ryumin |
|
Description: This module contains utility functions related to facial landmarks and image processing. |
|
License: MIT License |
|
""" |
|
|
|
import numpy as np |
|
import math |
|
import cv2 |
|
|
|
|
|
def norm_coordinates(normalized_x, normalized_y, image_width, image_height): |
|
x_px = min(math.floor(normalized_x * image_width), image_width - 1) |
|
y_px = min(math.floor(normalized_y * image_height), image_height - 1) |
|
return x_px, y_px |
|
|
|
|
|
def get_box(fl, w, h): |
|
idx_to_coors = {} |
|
for idx, landmark in enumerate(fl.landmark): |
|
landmark_px = norm_coordinates(landmark.x, landmark.y, w, h) |
|
if landmark_px: |
|
idx_to_coors[idx] = landmark_px |
|
|
|
x_min = np.min(np.asarray(list(idx_to_coors.values()))[:, 0]) |
|
y_min = np.min(np.asarray(list(idx_to_coors.values()))[:, 1]) |
|
endX = np.max(np.asarray(list(idx_to_coors.values()))[:, 0]) |
|
endY = np.max(np.asarray(list(idx_to_coors.values()))[:, 1]) |
|
|
|
(startX, startY) = (max(0, x_min), max(0, y_min)) |
|
(endX, endY) = (min(w - 1, endX), min(h - 1, endY)) |
|
|
|
return startX, startY, endX, endY |
|
|
|
def display_info(img, text, margin=1.0, box_scale=1.0): |
|
img_copy = img.copy() |
|
img_h, img_w, _ = img_copy.shape |
|
line_width = int(min(img_h, img_w) * 0.001) |
|
thickness = max(int(line_width / 3), 1) |
|
|
|
font_face = cv2.FONT_HERSHEY_SIMPLEX |
|
font_color = (0, 0, 0) |
|
font_scale = thickness / 1.5 |
|
|
|
t_w, t_h = cv2.getTextSize(text, font_face, font_scale, None)[0] |
|
|
|
margin_n = int(t_h * margin) |
|
sub_img = img_copy[0 + margin_n: 0 + margin_n + t_h + int(2 * t_h * box_scale), |
|
img_w - t_w - margin_n - int(2 * t_h * box_scale): img_w - margin_n] |
|
|
|
white_rect = np.ones(sub_img.shape, dtype=np.uint8) * 255 |
|
|
|
img_copy[0 + margin_n: 0 + margin_n + t_h + int(2 * t_h * box_scale), |
|
img_w - t_w - margin_n - int(2 * t_h * box_scale):img_w - margin_n] = cv2.addWeighted(sub_img, 0.5, white_rect, .5, 1.0) |
|
|
|
cv2.putText(img=img_copy, |
|
text=text, |
|
org=(img_w - t_w - margin_n - int(2 * t_h * box_scale) // 2, |
|
0 + margin_n + t_h + int(2 * t_h * box_scale) // 2), |
|
fontFace=font_face, |
|
fontScale=font_scale, |
|
color=font_color, |
|
thickness=thickness, |
|
lineType=cv2.LINE_AA, |
|
bottomLeftOrigin=False) |
|
|
|
return img_copy |
|
|