File size: 5,104 Bytes
cc46889
d310413
cc46889
 
 
 
 
6b52889
cc46889
 
6b52889
 
 
 
 
cc46889
6b52889
 
 
 
 
 
 
 
06ba967
6b52889
 
cc46889
6b52889
cc46889
6b52889
 
 
 
 
 
 
 
 
 
 
 
cc46889
6b52889
 
 
 
 
 
 
 
 
 
cc46889
 
6b52889
 
 
cc46889
6b52889
 
 
 
 
 
cc46889
6b52889
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc46889
6b52889
 
 
cc46889
6b52889
 
 
cc46889
6b52889
 
 
 
 
 
 
 
 
 
 
 
cc46889
 
 
6b52889
 
cc46889
6b52889
cc46889
6b52889
cc46889
 
 
6b52889
cc46889
8afa4d1
cc46889
 
 
6b52889
 
cc46889
 
6b52889
cc46889
6b52889
 
 
cc46889
 
6b52889
a7c179a
cc46889
 
 
 
6b52889
cc46889
 
 
 
 
6b52889
8f2f623
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Streamlit App for Workout Tracker
import streamlit as st
import cv2
import mediapipe as mp
import numpy as np
import time
from sklearn.ensemble import IsolationForest

# Title and Introduction
st.title("Muscle Memory")
st.markdown("""
Welcome to the **Workout Tracker App**! 
Select your desired workout below, and the app will guide you through the exercise with real-time feedback.
""")

# Workout Options
st.header("Choose Your Workout")
workout_option = st.selectbox(
    "Available Workouts:",
    ["Bicep Curl", "Lateral Raise", "Shoulder Press"]
)

# Mediapipe utilities
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose


# Helper Functions
def calculate_angle(a, b, c):
    """Calculate the angle between three points."""
    a = np.array(a)
    b = np.array(b)
    c = np.array(c)

    radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
    angle = np.abs(np.degrees(radians))
    if angle > 180.0:
        angle = 360 - angle
    return angle


def draw_text_with_background(image, text, position, font, font_scale, color, thickness, bg_color, padding=10):
    """Draw text with a background on an image."""
    text_size = cv2.getTextSize(text, font, font_scale, thickness)[0]
    text_x, text_y = position
    box_coords = (
        (text_x - padding, text_y - padding),
        (text_x + text_size[0] + padding, text_y + text_size[1] + padding),
    )
    cv2.rectangle(image, box_coords[0], box_coords[1], bg_color, cv2.FILLED)
    cv2.putText(image, text, (text_x, text_y + text_size[1]), font, font_scale, color, thickness)


# Main Function to Track Workout
def track_workout():
    cap = cv2.VideoCapture(0)
    counter = 0  # Rep counter
    stage = None  # Movement stage
    max_reps = 10  # Max reps
    feedback = ""  # Real-time feedback for the video feed

    with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                st.error("Failed to access the webcam. Please ensure your webcam is enabled.")
                break

            # Convert frame to RGB
            image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            image.flags.writeable = False
            results = pose.process(image)

            # Convert back to BGR
            image.flags.writeable = True
            image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

            # Check if pose landmarks are detected
            if results.pose_landmarks:
                landmarks = results.pose_landmarks.landmark

                # Extract key joints
                shoulder = [
                    landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
                    landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y,
                ]
                elbow = [
                    landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x,
                    landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y,
                ]
                wrist = [
                    landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x,
                    landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y,
                ]

                # Calculate the angle
                angle = calculate_angle(shoulder, elbow, wrist)

                # Stage logic for counting reps
                if angle > 160 and stage != "down":
                    stage = "down"
                elif angle < 40 and stage == "down":
                    stage = "up"
                    counter += 1

                    # Feedback
                    if counter == max_reps:
                        feedback = "Workout Complete!"
                        break
                    else:
                        feedback = f"Rep {counter} completed!"

                # Draw the feedback on the frame
                draw_text_with_background(image, f"Reps: {counter}", (50, 50),
                                          cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, (0, 0, 0))
                draw_text_with_background(image, feedback, (50, 100),
                                          cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, (0, 0, 0))

                # Draw landmarks
                mp_drawing.draw_landmarks(
                    image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                    mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
                    mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                )

            # Display the video feed
            cv2.imshow("Workout Tracker", image)

            # Break if 'q' is pressed
            if cv2.waitKey(10) & 0xFF == ord("q"):
                break

        cap.release()
        cv2.destroyAllWindows()


# Button to Start the Workout
if st.button("Start Workout"):
    st.write(f"Starting {workout_option} workout...")
    track_workout()

# Footer
st.markdown("""
---
**Note**: Press "q" in the webcam feed to stop the workout. Ensure your webcam is enabled.
""")