Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

yolov8x-seg.pt
151 changes: 151 additions & 0 deletions Functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
def mediapipe_estimation(path):
import cv2
import mediapipe as mp
import numpy as np

mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose

data = {
"NOSE":[],
"LEFT_EYE_INNER":[],
"LEFT_EYE":[],
"LEFT_EYE_OUTER":[],
"RIGHT_EYE_INNER":[],
"RIGHT_EYE":[],
"RIGHT_EYE_OUTER":[],
"LEFT_EAR":[],
"RIGHT_EAR":[],
"MOUTH_LEFT":[],
"MOUTH_RIGHT":[],
"LEFT_SHOULDER":[],
"RIGHT_SHOULDER":[],
"LEFT_ELBOW":[],
"RIGHT_ELBOW":[],
"LEFT_WRIST":[],
"RIGHT_WRIST":[],
"LEFT_PINKY":[],
"RIGHT_PINKY":[],
"LEFT_INDEX":[],
"RIGHT_INDEX":[],
"LEFT_THUMB":[],
"RIGHT_THUMB":[],
"LEFT_HIP":[],
"RIGHT_HIP":[],
"LEFT_KNEE":[],
"RIGHT_KNEE":[],
"LEFT_ANKLE":[],
"RIGHT_ANKLE":[],
"LEFT_HEEL":[],
"RIGHT_HEEL":[],
"LEFT_FOOT_INDEX":[],
"RIGHT_FOOT_INDEX":[]
}

#For video
cap = cv2.VideoCapture(path)
# Obtiene la velocidad de fotogramas (fps)

x = 0
y = 1

if not cap.isOpened():
print('Failed opening video')
else:
print("Starting...")
empty = []
images = []
frame_num = 0
with mp_pose.Pose(
min_detection_confidence=0.5,
min_tracking_confidence=0.75,
smooth_landmarks=True,
model_complexity = 2) as pose:
while cap.isOpened():
success, image = cap.read()
frame_num += 1
if not success:
print("End of video.")
break
# To improve performance, optionally mark the image as not writeable to
# pass by reference.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image)
#Store the data
if isinstance(results.pose_landmarks, type(None)):
#Adding frame with its index
empty.append(frame_num)
else:
for key, i in zip(data.keys(), range(33)):
data[key].append([results.pose_landmarks.landmark[i].x, results.pose_landmarks.landmark[i].y, results.pose_landmarks.landmark[i].z])
#Draw the landmarks
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
mp_drawing.draw_landmarks(
image,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style())
#Save the image in a mtrix
images.append(image)
# Flip the image horizontally for a selfie-view display.
#Make them numpy
for key in data.keys():
data[key] = np.array(data[key])
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
cap.release()

for keys in data.keys():
for i in range(len(data[keys][:])):
cv2.circle(images[i], (int(data[keys][i,x]*width), int(data[keys][i,y]*height)), radius=5, color=[255,0,0], thickness=-1)
return(images,width,height,data,keys)


def angle_estimation(vertex1, vertex2, vertex3):
import math
# Calcula la longitud de cada lado del triángulo
a = math.dist(vertex3, vertex2)
b = math.dist(vertex1, vertex3)
c = math.dist(vertex2, vertex1)
# Calcula el coseno del ángulo central correspondiente al lado b
cos_B = (a**2 + c**2 - b**2) / (2 * a * c)
# Calcula el ángulo central correspondiente al lado b
angle = math.acos(cos_B)
angle = math.degrees(angle)
angle = abs(angle)
return(angle)

def video_exportation(images,name):
import moviepy.editor as mpy
# Crear un clip de ejemplo con un par de cuadros
fps = 30 # cuadros por segundo
# Crear un clip a partir de los cuadros
clip = mpy.ImageSequenceClip(images, fps=fps)
# Guardar el clip en formato mp4
clip.write_videofile(name)

def angle_draw(arx, brx, ary, bry, alx, blx, aly, bly, angler, anglel, frame, width, height):
"""
hemmm, calcula el angulo para graficarlo xd


"""
import math
import cv2
dist_abr_y = abs(ary - bry)
dist_abr_x = abs(arx - brx)
dist_abl_y = abs(aly - bly)
dist_abl_x = abs(alx - blx)
start_angle_r = math.atan(dist_abr_y / dist_abr_x)
start_angle_r = math.degrees(start_angle_r)
start_angle_l = math.atan(dist_abl_y / dist_abl_x)
start_angle_l = math.degrees(start_angle_l)
if(abs(arx < brx)):
cv2.ellipse(frame, (int(brx * width), int(bry * height)), (25, 25), 0, (start_angle_r + 180 - angler), ((start_angle_r + 180 - angler) + angler), (0, 0, 0), 5)
cv2.ellipse(frame, (int(blx * width), int(bly * height)), (25, 25), 0, (start_angle_l + 180 - anglel), ((start_angle_l + 180 - anglel) + anglel), (0, 0, 0), 5)
else:
cv2.ellipse(frame, (int(brx * width), int(bry * height)), (25, 25), 0, (start_angle_r ), ((start_angle_r ) + angler), (0, 255, 0), 5)
cv2.ellipse(frame, (int(blx * width), int(bly * height)), (25, 25), 0, (start_angle_l ), ((start_angle_l ) + anglel), (0, 255, 0), 5)
119 changes: 119 additions & 0 deletions Interfaz.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import tkinter
from tkinter import filedialog
from Squat import squat_ana
from Pull_up import pull_up_ana
from Push_up import Push_up_ana
from Position import Posture_ana


Patient_main = tkinter.Tk()
Patient_main.geometry("1280x720")
Patient_main.resizable("false","false")

def load_archive_squat():
video_path = filedialog.askopenfilename(filetypes=[("all video files",".mp4")])
squat_ana(video_path,Video_label,Info_posture,Load_button_squat)

def load_archive_pull_up():
video_path = filedialog.askopenfilename(filetypes=[("all video files",".mp4")])
pull_up_ana(video_path,Video_label,Info_posture,Load_button_pull_up)

def load_archive_push_up():
video_path = filedialog.askopenfilename(filetypes=[("all video files",".mp4")])
Push_up_ana(video_path,Video_label,Info_posture,Load_button_pull_up)

def load_archive_posture():
image_path = filedialog.askopenfilename(filetypes=[("all images files",".jpeg")])
Posture_ana(image_path,Image_label)

#Analyzer button widgets
Info_posture = tkinter.Label(Patient_main, text="Select a video to start", font="Arial 18", fg="red")
Squat_recomendations = tkinter.Label(Patient_main, text= "Load a video preferably from a side view (sagittal plane)", font="Arial 12")
Pull_up_recomendations = tkinter.Label(Patient_main, text= "Load a video preferably from a front view (coronal plane)", font="Arial 12")
Push_up_recomendations = tkinter.Label(Patient_main, text= "Load a video preferably from a side view (sagittal plane)", font="Arial 12")
Posture_recomendations = tkinter.Label(Patient_main, text= "Load a image preferably from a side view (sagittal plane)", font="Arial 12")
Load_button_squat = tkinter.Button(Patient_main, text="Load", command=load_archive_squat,width=10, height=1)
Load_button_pull_up = tkinter.Button(Patient_main, text="Load", command=load_archive_pull_up,width=10, height=1)
Load_button_push_up = tkinter.Button(Patient_main, text="Load", command=load_archive_push_up,width=10, height=1)
Load_button_posture = tkinter.Button(Patient_main, text="Load", command=load_archive_posture,width=10, height=1)
Video_label = tkinter.Label(Patient_main)
Image_label = tkinter.Label(Patient_main)


def show_squat_recomendations():
hide_pull_up_recomendations()
hide_push_up_recomendations()
hide_posture_recomendations()
Info_posture.grid(column=5, row=0)
Squat_recomendations.grid(column= 5, row= 1)
Load_button_squat.grid(column=10, row=1)
Video_label.place(x=700, y=150)

def show_pull_up_recomendations():
hide_squat_recomendations()
hide_push_up_recomendations()
hide_posture_recomendations()
Info_posture.grid(column=5, row=0)
Pull_up_recomendations.grid(column= 5, row= 1)
Load_button_pull_up.grid(column=10, row=1)
Video_label.place(x=700, y=150)

def show_push_up_recomendations():
hide_pull_up_recomendations()
hide_squat_recomendations()
hide_posture_recomendations()
Info_posture.grid(column=5, row=0)
Push_up_recomendations.grid(column= 5, row= 1)
Load_button_push_up.grid(column=10, row=1)
Video_label.place(x=400, y=150)

def hide_pull_up_recomendations():
Info_posture.grid_remove()
Load_button_pull_up.grid_remove()
Pull_up_recomendations.grid_remove()
Video_label.place_forget()

def hide_squat_recomendations():
Info_posture.grid_remove()
Load_button_squat.grid_remove()
Squat_recomendations.grid_remove()
Video_label.place_forget()

def hide_push_up_recomendations():
Info_posture.grid_remove()
Push_up_recomendations.grid_remove()
Load_button_squat.grid_remove()
Video_label.place_forget()

def show_posture_recomendations():
hide_pull_up_recomendations()
hide_squat_recomendations()
hide_push_up_recomendations()
Info_posture.grid(column=5, row=0)
Posture_recomendations.grid(column= 5, row= 1)
Load_button_posture.grid(column=10, row=1)
Image_label.place(x=400, y=150)

def hide_posture_recomendations():
Info_posture.grid_remove()
Posture_recomendations.grid_remove()
Load_button_posture.grid_remove()
Image_label.place_forget()


Buttons_background = tkinter.Canvas(Patient_main, width=280, height=720)
Buttons_background.place(x=0,y=0)

Squat_button = tkinter.Button(Patient_main, text="Squat analyzer", font="Arial 12",command=show_squat_recomendations, width=25, height=2,wraplength=200)
Pull_up_button = tkinter.Button(Patient_main, text="Pull up analyzer", font="Arial 12",command=show_pull_up_recomendations, width=25, height=2,wraplength=200)
Push_up_button = tkinter.Button(Patient_main, text="Push up analyzer", font="Arial 12",command=show_push_up_recomendations, width=25, height=2,wraplength=200)
Posture_button = tkinter.Button(Patient_main, text="Posture analyzer", font="Arial 12",command=show_posture_recomendations, width=25, height=2,wraplength=200)

Squat_button.grid(column=0,row=0,padx=25,pady=25)
Pull_up_button.grid(column=0,row=1)
Push_up_button.grid(column=0,row=2, pady=25)
Posture_button.grid(column=0,row=3)

Buttons_background.create_rectangle(0, 0, 280, 720, fill="green")

Patient_main.mainloop()
Loading