Spaces:
Sleeping
Sleeping
| import cv2 | |
| import numpy as np | |
| from typing import List, Iterable | |
| import mediapipe as mp | |
| def detect_landmarks(src: np.ndarray, is_stream: bool = False): | |
| """ | |
| Given an image `src` retrieves the facial landmarks associated with it | |
| """ | |
| with mp.solutions.face_mesh.FaceMesh(static_image_mode=not is_stream, max_num_faces=1) as fm: | |
| results = fm.process(cv2.cvtColor(src, cv2.COLOR_BGR2RGB)) | |
| if results.multi_face_landmarks: | |
| return results.multi_face_landmarks[0].landmark | |
| return None | |
| def normalize_landmarks(landmarks, height: int, width: int, mask: Iterable = None): | |
| """ | |
| The landmarks returned by mediapipe have coordinates between [0, 1]. | |
| This function normalizes them in the range of the image dimensions so they can be played with. | |
| """ | |
| normalized_landmarks = np.array([(int(landmark.x * width), int(landmark.y * height)) for landmark in landmarks]) | |
| if mask: | |
| normalized_landmarks = normalized_landmarks[mask] | |
| return normalized_landmarks | |
| def plot_landmarks(src: np.array, landmarks: List, show: bool = False): | |
| """ | |
| Given a source image and a list of landmarks plots them onto the image | |
| """ | |
| dst = src.copy() | |
| for x, y in landmarks: | |
| cv2.circle(dst, (x, y), 2, 0, cv2.FILLED) | |
| if show: | |
| print("Displaying image plotted with landmarks") | |
| cv2.imshow("Plotted Landmarks", dst) | |
| return dst | |