-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathlandmarks.py
39 lines (33 loc) · 1.4 KB
/
landmarks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import cv2
import numpy as np
from typing import List, Iterable
from mediapipe.python.solutions.face_mesh import FaceMesh
def detect_landmarks(src: np.ndarray, is_stream: bool = False):
"""
Given an image `src` retrieves the facial landmarks associated with it
"""
with FaceMesh(static_image_mode=not is_stream, max_num_faces=1) as face_mesh:
results = face_mesh.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