HEMANTH commited on
Commit
ed84fc7
·
1 Parent(s): 0c22539

test1 with media pipe

Browse files
Files changed (5) hide show
  1. Dockerfile +16 -0
  2. app.py +127 -0
  3. requirements.txt +5 -0
  4. templates/index.html +15 -0
  5. uploads/shoulderpress.mp4 +0 -0
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+ CMD ["gunicorn", "-b", "0.0.0.0:7860","app:app"]
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, Response
2
+ import cv2
3
+ import mediapipe as mp
4
+ import numpy as np
5
+ import os
6
+
7
+ app = Flask(__name__)
8
+
9
+ # Initialize Mediapipe Pose
10
+ mp_pose = mp.solutions.pose
11
+ mp_drawing = mp.solutions.drawing_utils
12
+
13
+ # Function to calculate the angle between three points
14
+ def calculate_angle(a, b, c):
15
+ a = np.array(a) # First point
16
+ b = np.array(b) # Middle point
17
+ c = np.array(c) # Last point
18
+
19
+ radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
20
+ angle = np.abs(radians * 180.0 / np.pi)
21
+
22
+ if angle > 180.0:
23
+ angle = 360 - angle
24
+
25
+ return angle
26
+
27
+ # Function to check shoulder press posture
28
+ def is_shoulder_press_correct(landmarks, mp_pose):
29
+ # Get coordinates of shoulder, elbow, and wrist (left arm as example)
30
+ shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
31
+ landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
32
+ elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x,
33
+ landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y]
34
+ wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x,
35
+ landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y]
36
+
37
+ # Calculate angle at the elbow (shoulder, elbow, wrist)
38
+ elbow_angle = calculate_angle(shoulder, elbow, wrist)
39
+
40
+ # Check if the motion is vertical (wrist higher than elbow)
41
+ if wrist[1] < elbow[1] and elbow[1] < shoulder[1]:
42
+ # Ensure proper angle range for a shoulder press
43
+ if 160 <= elbow_angle <= 180:
44
+ return "Shoulder Press: Correct", True
45
+ else:
46
+ return "Shoulder Press: Incorrect - Elbow angle", False
47
+ else:
48
+ return "Shoulder Press: Incorrect - Alignment", False
49
+
50
+ # Video processing function
51
+ def process_video(video_path):
52
+ cap = cv2.VideoCapture(video_path)
53
+ count = 0
54
+ rep_started = False
55
+
56
+ with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
57
+ while cap.isOpened():
58
+ ret, frame = cap.read()
59
+ if not ret:
60
+ break
61
+
62
+ # Convert the frame to RGB
63
+ image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
64
+ image.flags.writeable = False
65
+
66
+ # Process the image for pose detection
67
+ results = pose.process(image)
68
+
69
+ # Convert back to BGR for rendering
70
+ image.flags.writeable = True
71
+ image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
72
+
73
+ # Extract landmarks
74
+ if results.pose_landmarks:
75
+ landmarks = results.pose_landmarks.landmark
76
+
77
+ # Check shoulder press posture
78
+ feedback, is_correct = is_shoulder_press_correct(landmarks, mp_pose)
79
+
80
+ # Count reps
81
+ if is_correct and not rep_started:
82
+ rep_started = True
83
+ elif not is_correct and rep_started:
84
+ rep_started = False
85
+ count += 1
86
+
87
+ # Display feedback
88
+ cv2.putText(image, feedback, (50, 50),
89
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0) if is_correct else (0, 0, 255), 2, cv2.LINE_AA)
90
+
91
+ # Display rep count
92
+ cv2.putText(image, f'Reps: {count}', (50, 100),
93
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
94
+
95
+ # Draw landmarks
96
+ mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
97
+
98
+ else:
99
+ # Warn if no landmarks are detected
100
+ cv2.putText(image, "No body detected", (50, 50),
101
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
102
+
103
+ # Encode frame for streaming
104
+ ret, buffer = cv2.imencode('.jpg', image)
105
+ frame = buffer.tobytes()
106
+ yield (b'--frame\r\n'
107
+ b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
108
+
109
+ cap.release()
110
+
111
+ @app.route('/')
112
+ def index():
113
+ return render_template('index.html')
114
+
115
+ @app.route('/upload', methods=['POST'])
116
+ def upload():
117
+ if 'video' not in request.files:
118
+ return "No video file uploaded", 400
119
+
120
+ video = request.files['video']
121
+ video_path = os.path.join('uploads', video.filename)
122
+ video.save(video_path)
123
+
124
+ return Response(process_video(video_path), mimetype='multipart/x-mixed-replace; boundary=frame')
125
+
126
+ if __name__ == "__main__":
127
+ app.run(debug=True)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Flask
2
+ opencv-python-headless
3
+ mediapipe
4
+ numpy
5
+ gunicorn
templates/index.html ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Shoulder Press Detection</title>
7
+ </head>
8
+ <body>
9
+ <h1>Upload Your Shoulder Press Video</h1>
10
+ <form action="/upload" method="post" enctype="multipart/form-data">
11
+ <input type="file" name="video" accept="video/*" required>
12
+ <button type="submit">Upload and Analyze</button>
13
+ </form>
14
+ </body>
15
+ </html>
uploads/shoulderpress.mp4 ADDED
Binary file (266 kB). View file