Spaces:
Sleeping
Sleeping
import base64 | |
import os | |
import requests | |
import cv2 | |
import numpy as np | |
from PIL import Image | |
from .exceptions import InvalidImage | |
from .emotionsmultilanguage import emotions_dict | |
def draw_annotations( | |
frame: np.ndarray, | |
faces: list, | |
boxes=True, | |
scores=True, | |
color: tuple = (0, 155, 255), | |
lang: str = "en", | |
size_multiplier: int = 1, | |
) -> np.ndarray: | |
"""Draws boxes around detected faces. Faces is a list of dicts with `box` and `emotions`.""" | |
if not len(faces): | |
return frame | |
for face in faces: | |
x, y, w, h = face["box"] | |
emotions = face["emotions"] | |
if boxes: | |
cv2.rectangle( | |
frame, | |
(x, y, w, h), | |
color, | |
2, | |
) | |
if scores: | |
frame = draw_scores(frame, emotions, (x, y, w, h), lang, size_multiplier) | |
return frame | |
def loadBase64Img(uri): | |
encoded_data = uri.split(",")[1] | |
nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8) | |
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) | |
return img | |
def pil_to_bgr(pil_image): | |
return cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR) | |
def load_image(img): | |
"""Modified from github.com/serengil/deepface. Returns bgr (opencv-style) numpy array.""" | |
is_exact_image = is_base64_img = is_url_img = False | |
if type(img).__module__ == np.__name__: | |
is_exact_image = True | |
elif img is None: | |
raise InvalidImage("Image not valid.") | |
elif len(img) > 11 and img[0:11] == "data:image/": | |
is_base64_img = True | |
elif len(img) > 11 and img.startswith("http"): | |
is_url_img = True | |
if is_base64_img: | |
img = loadBase64Img(img) | |
elif is_url_img: | |
img = pil_to_bgr(Image.open(requests.get(img, stream=True).raw)) | |
elif not is_exact_image: # image path passed as input | |
if not os.path.isfile(img): | |
raise ValueError(f"Confirm that {img} exists") | |
img = cv2.imread(img) | |
if img is None or not hasattr(img, "shape"): | |
raise InvalidImage("Image not valid.") | |
return img | |
def draw_scores( | |
frame: np.ndarray, | |
emotions: dict, | |
bounding_box: dict, | |
lang: str = "en", | |
size_multiplier: int = 1, | |
) -> np.ndarray: | |
"""Draw scores for each emotion under faces.""" | |
GRAY = (211, 211, 211) | |
GREEN = (0, 255, 0) | |
x, y, w, h = bounding_box | |
for idx, (emotion, score) in enumerate(emotions.items()): | |
color = GRAY if score < 0.01 else GREEN | |
if lang != "en": | |
emotion = emotions_dict[emotion][lang] | |
emotion_score = "{}: {}".format( | |
emotion, "{:.2f}".format(score) if score >= 0.01 else "" | |
) | |
cv2.putText( | |
frame, | |
emotion_score, | |
( | |
x, | |
y + h + (15 * size_multiplier) + idx * (15 * size_multiplier), | |
), | |
cv2.FONT_HERSHEY_SIMPLEX, | |
0.5 * size_multiplier, | |
color, | |
1 * size_multiplier, | |
cv2.LINE_AA, | |
) | |
return frame | |