Spaces:
Build error
Build error
| import gradio as gr | |
| import math | |
| import time | |
| import mediapipe as mp | |
| import cv2 | |
| from PIL import Image | |
| import numpy as np | |
| import datetime | |
| import copy | |
| from openpose import util | |
| from openpose.body import Body | |
| import matplotlib.pyplot as plt | |
| mp_pose = mp.solutions.pose | |
| pose = mp_pose.Pose(static_image_mode=True, min_detection_confidence=0.3, model_complexity=2) | |
| mp_drawing = mp.solutions.drawing_utils | |
| def change_example(choice): | |
| if choice == "plank": | |
| return gr.Image.update(value="examples/plank.jpg") | |
| elif choice == "downdog": | |
| return gr.update(value="examples/downdog.jpg") | |
| elif choice == "tree": | |
| return gr.update(value="examples/tree.jpg") | |
| else: | |
| return gr.update(visible=False) | |
| def points(image): | |
| results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) | |
| image_height, image_width, _ = image.shape | |
| img_copy = image.copy() | |
| if results.pose_landmarks: | |
| mp_drawing.draw_landmarks(image=img_copy, landmark_list=results.pose_landmarks, connections=mp_pose.POSE_CONNECTIONS) | |
| img = plt.figure(figsize = [10, 10]) | |
| plt.axis('off') | |
| plt.imshow(img_copy[:,:,::-1]) | |
| return img | |
| else: | |
| return gr.Image("examples/Error.png") | |
| def landmarks(image): | |
| results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) | |
| height, width, _ = image.shape | |
| landmarks = [] | |
| if results.pose_landmarks: | |
| for landmark in results.pose_landmarks.landmark: | |
| landmarks.append((int(landmark.x * width), int(landmark.y * height), | |
| (landmark.z * width))) | |
| return landmarks | |
| def calculateAngle(landmark1, landmark2, landmark3): | |
| x1, y1, _ = landmark1 | |
| x2, y2, _ = landmark2 | |
| x3, y3, _ = landmark3 | |
| angle = math.degrees(math.atan2(y3 - y2, x3 - x2) - math.atan2(y1 - y2, x1 - x2)) | |
| if angle < 0: | |
| angle += 360 | |
| if angle > 180: | |
| angle = 360 - angle | |
| return angle | |
| def correct_plank(landmarks): | |
| recommendation = "" | |
| result = "" | |
| left_knee_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value]) | |
| right_knee_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value]) | |
| left_hip_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]) | |
| right_hip_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]) | |
| if (left_knee_angle>180 or left_knee_angle<170): | |
| recommendation = recommendation + "The left knee should be straight. " | |
| if (right_knee_angle>180 or right_knee_angle<170): | |
| recommendation = recommendation + "The right knee should be straight. " | |
| if ((left_hip_angle>180 or left_hip_angle<170) or (right_hip_angle>180 or right_hip_angle<170)): | |
| recommendation = recommendation + "The spine should be straight. " | |
| if recommendation == "": | |
| result = "Great! You are doing the exercise correctly" | |
| else: | |
| result = "Almost perfect, but \n" | |
| return result + recommendation | |
| def correct_dog(landmarks): | |
| recommendation = "" | |
| result = "" | |
| left_hip_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]) | |
| right_hip_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]) | |
| left_leg = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value]) | |
| right_leg = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value]) | |
| right_hand = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value]) | |
| left_hand = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value]) | |
| if (left_hip_angle>90 or right_hip_angle>90): | |
| recommendation += "The spine should be bent. " | |
| if not (170 < left_leg < 181 or 170 < right_leg < 181): | |
| recommendation = "Legs should be straight. " | |
| if not (170 < left_hand < 181 or 181 > right_hand > 170): | |
| recommendation = "Hands should be straight. " | |
| if recommendation == "": | |
| result = "Great! You are doing the exercise correctly" | |
| else: | |
| result = "Almost perfect, but \n" | |
| return result + recommendation | |
| def correct_tree(landmarks): | |
| recommendation = "" | |
| result = "" | |
| left_hip_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]) | |
| right_hip_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]) | |
| left_leg = calculateAngle( | |
| landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value]) | |
| right_leg = calculateAngle( | |
| landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value]) | |
| right_hand = calculateAngle( | |
| landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value]) | |
| left_hand = calculateAngle( | |
| landmarks[mp_pose.PoseLandmark.LEFT_HIP.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value], | |
| landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value]) | |
| #if (left_hand>90 or right_hand>90): | |
| # recommendation += "Hands should be bent. " | |
| if not (((175 < right_leg < 181) and (left_leg < 100)) or ((175 < left_leg < 181) and (right_leg < 100))): | |
| recommendation = "One leg should be straight and another should be bent. " | |
| if recommendation == "": | |
| result = "Great! You are doing the exercise correctly" | |
| else: | |
| result = "Almost perfect, but \n" | |
| return result + recommendation | |
| def detect(video, radio): | |
| video_clip = cv2.VideoCapture(video) | |
| frames = video_clip.get(cv2.CAP_PROP_FRAME_COUNT) | |
| i=0 | |
| while(video_clip.isOpened()): | |
| is_read, frame = video_clip.read() | |
| image = frame | |
| if i == round(frames/2): | |
| image = frame | |
| break | |
| i+=1 | |
| new_image = points(image) | |
| result = "" | |
| if radio == "plank": | |
| result = correct_plank(landmarks(image)) | |
| if radio == "downdog": | |
| result = correct_dog(landmarks(image)) | |
| if radio == "tree": | |
| result = correct_tree(landmarks(image)) | |
| return new_image, result | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(): | |
| radio = gr.Radio(["plank", "downdog", "tree"], label="Choose the exercise") | |
| image1 = gr.Image("examples/Example.png") | |
| video = gr.Video(label="Upload video with exercise") | |
| check_btn = gr.Button(value="Let's go") | |
| with gr.Column(): | |
| image = gr.Plot() | |
| result = gr.Textbox() | |
| radio.change(fn=change_example, inputs=radio, outputs=image1) | |
| check_btn.click(detect, inputs=[video, radio], outputs=[image, result]) | |
| demo.launch() | |
| #gr.Interface( | |
| # fn=detect, | |
| # inputs=gr.Video(label="Upload video with exercise"), | |
| # outputs="image", | |
| # title="Are you doing the exercise correct?" | |
| #).launch() |