Healthy_fans / app.py
Stacy123's picture
Update app.py
f8d143b
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()