hf-similarity-check / Visualization_utilities.py
Mitul Mohammad Abdullah Al Mukit
first commit
1f72938
raw
history blame
7.59 kB
import cv2
import mediapipe as mp
from mediapipe import solutions
from mediapipe.framework.formats import landmark_pb2
import numpy as np
import math
# visualization libraries
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
def draw_eyes_on_image(rgb_image, detection_result):
# return rgb_image, 0, 0
# canonical_face_model_uv_visualization in the below link
# https://github.com/google/mediapipe/blob/a908d668c730da128dfa8d9f6bd25d519d006692/mediapipe/modules/face_geometry/data/canonical_face_model_uv_visualization.png
left_eyes_bottom_list = [33, 7, 163, 144, 145, 153, 154, 155, 133]
left_eyes_top_list = [246, 161, 160, 159, 158, 157, 173]
right_eyes_bottom_list = [362, 382, 381, 380, 374, 373, 390, 249, 263]
right_eyes_top_list = [398, 384, 385, 386, 387, 388, 466]
face_landmarks_list = detection_result.face_landmarks
annotated_image = np.copy(rgb_image)
# We resize image to 640 * 360
height, width, channels = rgb_image.shape
# Loop through the detected faces to visualize. Actually, if we detect more than two faces, we will require user closer to the camera
for idx in range(len(face_landmarks_list)):
face_landmarks = face_landmarks_list[idx]
mlist = []
for landmark in face_landmarks:
mlist.append([int(landmark.x * width), int(landmark.y * height), landmark.z])
narray = np.copy(mlist)
# Vertical line
#
#
# Pick the largest difference (middle of the eyes)
leftUp = narray[159]
leftDown = narray[145]
rightUp = narray[386]
rightDown = narray[374]
# compute left eye distance (vertical)
leftUp_x = int(leftUp[0])
leftUp_y = int(leftUp[1])
leftDown_x = int(leftDown[0])
leftDown_y = int(leftDown[1])
leftVerDis = math.dist([leftUp_x, leftUp_y],[leftDown_x, leftDown_y])
# compute right eye distance (vertical)
rightUp_x = int(rightUp[0])
rightUp_y = int(rightUp[1])
rightDown_x = int(rightDown[0])
rightDown_y = int(rightDown[1])
rightVerDis = math.dist([rightUp_x, rightUp_y],[rightDown_x, rightDown_y])
# print(f'leftVerDis: {leftVerDis} and rightVerDis: {rightVerDis}')
# draw a line from left eye top to bottom
annotated_image = cv2.line(rgb_image, (int(leftUp_x), int(leftUp_y)), (int(leftDown_x), int(leftDown_y)), (0, 200, 0), 1)
# draw a line from right eye top to bottom
annotated_image = cv2.line(rgb_image, (int(rightUp_x), int(rightUp_y)), (int(rightDown_x), int(rightDown_y)), (0, 200, 0), 1)
#
#
# Horizontonal line
#
#
# Pick the largest difference (middle of the eyes)
leftLeft = narray[33]
leftRight = narray[133]
rightLeft = narray[362]
rightRight = narray[263]
# compute left eye distance (horizontal)
leftLeft_x = int(leftLeft[0])
leftLeft_y = int(leftLeft[1])
leftRight_x = int(leftRight[0])
leftRight_y = int(leftRight[1])
leftHorDis = math.dist([leftLeft_x, leftLeft_y],[leftRight_x, leftRight_y])
# compute right eye distance (horizontal)
rightLeft_x = int(rightLeft[0])
rightLeft_y = int(rightLeft[1])
rightRight_x = int(rightRight[0])
rightRight_y = int(rightRight[1])
rightHorDis = math.dist([rightLeft_x, rightLeft_y],[rightRight_x, rightRight_y])
# print(f'leftHorDis: {leftHorDis} and rightHorDis: {rightHorDis}')
# draw a line from left eye top to bottom
annotated_image = cv2.line(rgb_image, (int(leftLeft_x), int(leftLeft_y)), (int(leftRight_x), int(leftRight_y)), (0, 200, 0), 1)
# draw a line from right eye top to bottom
annotated_image = cv2.line(rgb_image, (int(rightLeft_x), int(rightLeft_y)), (int(rightRight_x), int(rightRight_y)), (0, 200, 0), 1)
#
#
#
#
# print(f'leftRatio: {leftVerDis/leftHorDis} and rightRatio: {rightVerDis/rightHorDis}')
leftRatio = leftVerDis/leftHorDis*100
rightRatio = rightVerDis/rightHorDis*100
# left_eyes_bottom = [narray[x] for x in left_eyes_bottom_list]
# left_eyes_top = [narray[x] for x in left_eyes_top_list]
# right_eyes_bottom = [narray[x] for x in right_eyes_bottom_list]
# right_eyes_top = [narray[x] for x in right_eyes_top_list]
# for p in left_eyes_bottom:
# annotated_image = cv2.circle(rgb_image, (int(p[0]), int(p[1])), radius=1, color=(0,0,255), thickness=1)
# for p in left_eyes_top:
# annotated_image = cv2.circle(rgb_image, (int(p[0]), int(p[1])), radius=1, color=(0,0,255), thickness=1)
# for p in right_eyes_bottom:
# annotated_image = cv2.circle(rgb_image, (int(p[0]), int(p[1])), radius=1, color=(0,0,255), thickness=1)
# for p in right_eyes_top:
# annotated_image = cv2.circle(rgb_image, (int(p[0]), int(p[1])), radius=1, color=(0,0,255), thickness=1)
return annotated_image, leftRatio, rightRatio
def draw_landmarks_on_image(rgb_image, detection_result):
face_landmarks_list = detection_result.face_landmarks
annotated_image = np.copy(rgb_image)
# Loop through the detected faces to visualize. Actually, if we detect more than two faces, we will require user closer to the camera
for idx in range(len(face_landmarks_list)):
face_landmarks = face_landmarks_list[idx]
# Draw the face landmarks.
face_landmarks_proto = landmark_pb2.NormalizedLandmarkList()
face_landmarks_proto.landmark.extend([
landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y, z=landmark.z) for landmark in face_landmarks
])
solutions.drawing_utils.draw_landmarks(
image=annotated_image,
landmark_list=face_landmarks_proto,
connections=mp.solutions.face_mesh.FACEMESH_TESSELATION,
landmark_drawing_spec=None,
connection_drawing_spec=mp.solutions.drawing_styles
.get_default_face_mesh_tesselation_style())
solutions.drawing_utils.draw_landmarks(
image=annotated_image,
landmark_list=face_landmarks_proto,
connections=mp.solutions.face_mesh.FACEMESH_CONTOURS,
landmark_drawing_spec=None,
connection_drawing_spec=mp.solutions.drawing_styles
.get_default_face_mesh_contours_style())
solutions.drawing_utils.draw_landmarks(
image=annotated_image,
landmark_list=face_landmarks_proto,
connections=mp.solutions.face_mesh.FACEMESH_IRISES,
landmark_drawing_spec=None,
connection_drawing_spec=mp.solutions.drawing_styles
.get_default_face_mesh_iris_connections_style())
return annotated_image
def plot_face_blendshapes_bar_graph(face_blendshapes):
# Extract the face blendshapes category names and scores.
face_blendshapes_names = [face_blendshapes_category.category_name for face_blendshapes_category in face_blendshapes]
face_blendshapes_scores = [face_blendshapes_category.score for face_blendshapes_category in face_blendshapes]
# The blendshapes are ordered in decreasing score value.
face_blendshapes_ranks = range(len(face_blendshapes_names))
fig, ax = plt.subplots(figsize=(12, 12))
bar = ax.barh(face_blendshapes_ranks, face_blendshapes_scores, label=[str(x) for x in face_blendshapes_ranks])
ax.set_yticks(face_blendshapes_ranks, face_blendshapes_names)
ax.invert_yaxis()
# Label each bar with values
for score, patch in zip(face_blendshapes_scores, bar.patches):
plt.text(patch.get_x() + patch.get_width(), patch.get_y(), f"{score:.4f}", va="top")
ax.set_xlabel('Score')
ax.set_title("Face Blendshapes")
plt.tight_layout()
plt.show()