Spaces:
Configuration error
Configuration error
import mediapipe as mp | |
import cv2 | |
from django.conf import settings | |
from .plank import PlankDetection | |
from .bicep_curl import BicepCurlDetection | |
from .squat import SquatDetection | |
from .lunge import LungeDetection | |
from .utils import rescale_frame | |
# Drawing helpers | |
mp_drawing = mp.solutions.drawing_utils | |
mp_pose = mp.solutions.pose | |
EXERCISE_DETECTIONS = None | |
def load_machine_learning_models(): | |
"""Load all machine learning models""" | |
global EXERCISE_DETECTIONS | |
if EXERCISE_DETECTIONS is not None: | |
return | |
print("Loading ML models ...") | |
EXERCISE_DETECTIONS = { | |
"plank": PlankDetection(), | |
"bicep_curl": BicepCurlDetection(), | |
"squat": SquatDetection(), | |
"lunge": LungeDetection(), | |
} | |
def pose_detection( | |
video_file_path: str, video_name_to_save: str, rescale_percent: float = 40 | |
): | |
"""Pose detection with MediaPipe Pose | |
Args: | |
video_file_path (str): path to video | |
video_name_to_save (str): path to save analyzed video | |
rescale_percent (float, optional): Percentage to scale back from the original video size. Defaults to 40. | |
""" | |
cap = cv2.VideoCapture(video_file_path) | |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) * rescale_percent / 100) | |
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) * rescale_percent / 100) | |
size = (width, height) | |
fps = int(cap.get(cv2.CAP_PROP_FPS)) | |
fourcc = cv2.VideoWriter_fourcc(*"avc1") | |
save_to_path = f"{settings.MEDIA_ROOT}/{video_name_to_save}" | |
out = cv2.VideoWriter(save_to_path, fourcc, fps, size) | |
print("PROCESSING VIDEO ...") | |
with mp_pose.Pose( | |
min_detection_confidence=0.8, min_tracking_confidence=0.8 | |
) as pose: | |
while cap.isOpened(): | |
ret, image = cap.read() | |
if not ret: | |
break | |
image = rescale_frame(image, rescale_percent) | |
# Recolor image from BGR to RGB for mediapipe | |
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
image.flags.writeable = False | |
results = pose.process(image) | |
# Recolor image from BGR to RGB for mediapipe | |
image.flags.writeable = True | |
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) | |
mp_drawing.draw_landmarks( | |
image, | |
results.pose_landmarks, | |
mp_pose.POSE_CONNECTIONS, | |
mp_drawing.DrawingSpec( | |
color=(244, 117, 66), thickness=2, circle_radius=2 | |
), | |
mp_drawing.DrawingSpec( | |
color=(245, 66, 230), thickness=2, circle_radius=1 | |
), | |
) | |
out.write(image) | |
print(f"PROCESSED, save to {save_to_path}.") | |
return | |
def exercise_detection( | |
video_file_path: str, | |
video_name_to_save: str, | |
exercise_type: str, | |
rescale_percent: float = 40, | |
) -> dict: | |
"""Analyzed Exercise Video | |
Args: | |
video_file_path (str): path to video | |
video_name_to_save (str): path to save analyzed video | |
exercise_type (str): exercise type | |
rescale_percent (float, optional): Percentage to scale back from the original video size. Defaults to 40. | |
Raises: | |
Exception: Not supported exercise type | |
Returns: | |
dict: Dictionary of analyzed stats from the video | |
""" | |
exercise_detection = EXERCISE_DETECTIONS.get(exercise_type) | |
if not exercise_detection: | |
raise Exception("Not supported exercise.") | |
cap = cv2.VideoCapture(video_file_path) | |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) * rescale_percent / 100) | |
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) * rescale_percent / 100) | |
size = (width, height) | |
fps = int(cap.get(cv2.CAP_PROP_FPS)) | |
frame_count = 0 | |
fourcc = cv2.VideoWriter_fourcc(*"avc1") | |
saved_path = f"{settings.MEDIA_ROOT}/{video_name_to_save}" | |
out = cv2.VideoWriter(saved_path, fourcc, fps, size) | |
print("PROCESSING VIDEO ...") | |
with mp_pose.Pose( | |
min_detection_confidence=0.8, min_tracking_confidence=0.8 | |
) as pose: | |
while cap.isOpened(): | |
ret, image = cap.read() | |
if not ret: | |
break | |
# Calculate timestamp | |
frame_count += 1 | |
timestamp = int(frame_count / fps) | |
image = rescale_frame(image, rescale_percent) | |
# Recolor image from BGR to RGB for mediapipe | |
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
image.flags.writeable = False | |
results = pose.process(image) | |
# Recolor image from BGR to RGB for mediapipe | |
image.flags.writeable = True | |
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) | |
if results.pose_landmarks: | |
exercise_detection.detect( | |
mp_results=results, image=image, timestamp=timestamp | |
) | |
out.write(image) | |
print(f"PROCESSED. Save path: {saved_path}") | |
processed_results = exercise_detection.handle_detected_results( | |
video_name=video_name_to_save | |
) | |
exercise_detection.clear_results() | |
return processed_results | |