Spaces:
Configuration error
Configuration error
| import mediapipe as mp | |
| import cv2 | |
| import numpy as np | |
| import datetime | |
| import os | |
| import math | |
| from django.conf import settings | |
| # Drawing helpers | |
| mp_drawing = mp.solutions.drawing_utils | |
| mp_pose = mp.solutions.pose | |
| # * Mediapipe Utils Functions | |
| def calculate_angle(point1: list, point2: list, point3: list) -> float: | |
| """Calculate the angle between 3 points | |
| Args: | |
| point1 (list): Point 1 coordinate | |
| point2 (list): Point 2 coordinate | |
| point3 (list): Point 3 coordinate | |
| Returns: | |
| float: angle in degree | |
| """ | |
| point1 = np.array(point1) | |
| point2 = np.array(point2) | |
| point3 = np.array(point3) | |
| # Calculate algo | |
| angleInRad = np.arctan2(point3[1] - point2[1], point3[0] - point2[0]) - np.arctan2( | |
| point1[1] - point2[1], point1[0] - point2[0] | |
| ) | |
| angleInDeg = np.abs(angleInRad * 180.0 / np.pi) | |
| angleInDeg = angleInDeg if angleInDeg <= 180 else 360 - angleInDeg | |
| return angleInDeg | |
| def calculate_distance(pointX: list, pointY: list) -> float: | |
| """Calculate distance between 2 points in a frame | |
| Args: | |
| pointX (list): First point coordinate | |
| pointY (list): Second point coordinate | |
| Returns: | |
| float: _description_ | |
| """ | |
| x1, y1 = pointX | |
| x2, y2 = pointY | |
| return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) | |
| def extract_important_keypoints(results, important_landmarks: list) -> list: | |
| """Extract important landmarks' data from MediaPipe output | |
| Args: | |
| results : MediaPipe Pose output | |
| important_landmarks (list): list of important landmarks | |
| Returns: | |
| list: list of important landmarks' data from MediaPipe output | |
| """ | |
| landmarks = results.pose_landmarks.landmark | |
| data = [] | |
| for lm in important_landmarks: | |
| keypoint = landmarks[mp_pose.PoseLandmark[lm].value] | |
| data.append([keypoint.x, keypoint.y, keypoint.z, keypoint.visibility]) | |
| return np.array(data).flatten().tolist() | |
| def get_drawing_color(error: bool) -> tuple: | |
| """Get drawing color for MediaPipe Pose | |
| Args: | |
| error (bool): True if correct pose, False if incorrect pose | |
| Returns: | |
| tuple: RGB colors | |
| """ | |
| LIGHT_BLUE = (244, 117, 66) | |
| LIGHT_PINK = (245, 66, 230) | |
| LIGHT_RED = (29, 62, 199) | |
| LIGHT_YELLOW = (1, 143, 241) | |
| return (LIGHT_YELLOW, LIGHT_RED) if error else (LIGHT_BLUE, LIGHT_PINK) | |
| # * OpenCV util functions | |
| def rescale_frame(frame, percent=50): | |
| """Rescale a frame from OpenCV to a certain percentage compare to its original frame | |
| Args: | |
| frame: OpenCV frame | |
| percent (int, optional): percent to resize an old frame. Defaults to 50. | |
| Returns: | |
| _type_: OpenCV frame | |
| """ | |
| width = int(frame.shape[1] * percent / 100) | |
| height = int(frame.shape[0] * percent / 100) | |
| dim = (width, height) | |
| return cv2.resize(frame, dim, interpolation=cv2.INTER_AREA) | |
| def save_frame_as_image(frame, message: str = None): | |
| """ | |
| Save a frame as image to display the error | |
| """ | |
| now = datetime.datetime.now() | |
| if message: | |
| cv2.putText( | |
| frame, | |
| message, | |
| (50, 150), | |
| cv2.FONT_HERSHEY_COMPLEX, | |
| 0.4, | |
| (0, 0, 0), | |
| 1, | |
| cv2.LINE_AA, | |
| ) | |
| print("Saving ...") | |
| cv2.imwrite(f"../data/logs/bicep_{now}.jpg", frame) | |
| # * Other util functions | |
| def get_static_file_url(file_name: str) -> str: | |
| """Return static url of a file | |
| Args: | |
| file_name (str) | |
| Returns: | |
| str: Full absolute path of the file. Return None if file is not found | |
| """ | |
| path = f"{settings.STATICFILES_DIRS[0]}/{file_name}" | |
| print(path) | |
| return path if os.path.exists(path) else None | |