Spaces:
Sleeping
Sleeping
File size: 3,285 Bytes
f7c47ba cc9d1c9 f7c47ba f09e80a f7c47ba cc9d1c9 f7c47ba cc9d1c9 f7c47ba f09e80a f7c47ba f09e80a cc9d1c9 f09e80a cc9d1c9 f09e80a cc9d1c9 f09e80a cc9d1c9 f7c47ba cc9d1c9 f09e80a f7c47ba cc9d1c9 f7c47ba f09e80a f7c47ba cc9d1c9 f7c47ba cc9d1c9 f7c47ba cc9d1c9 f09e80a f7c47ba |
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 |
import cv2
import mediapipe as mp
import numpy as np
import gradio as gr
import os
mp_pose = mp.solutions.pose
mp_drawing = mp.solutions.drawing_utils
pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5, min_tracking_confidence=0.5)
def calculate_angle(a, b, c):
a = np.array(a)
b = np.array(b)
c = np.array(c)
ba = a - b
bc = c - b
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
angle = np.arccos(np.clip(cosine_angle, -1.0, 1.0))
return np.degrees(angle)
def detect_pose_video(video_path, max_duration=20):
if not os.path.exists(video_path):
return None
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise ValueError("Cannot open video file")
# Video properties
fps = cap.get(cv2.CAP_PROP_FPS) or 20.0
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) or 640)
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) or 480)
max_frames = int(fps * max_duration) # Limit to 20 seconds
out_path = "annotated_video.mp4"
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(out_path, fourcc, fps, (width, height))
frame_count = 0
while frame_count < max_frames:
ret, frame = cap.read()
if not ret:
break
# Resize if too big
max_dim = 640
h, w, _ = frame.shape
if max(h, w) > max_dim:
scale = max_dim / max(h, w)
frame = cv2.resize(frame, (int(w*scale), int(h*scale)))
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(frame_rgb)
if results.pose_landmarks:
mp_drawing.draw_landmarks(
frame,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(0,255,0), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(0,0,255), thickness=2)
)
# Example: left elbow angle
landmarks = results.pose_landmarks.landmark
shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x * frame.shape[1],
landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y * frame.shape[0]]
elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x * frame.shape[1],
landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y * frame.shape[0]]
wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x * frame.shape[1],
landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y * frame.shape[0]]
angle = calculate_angle(shoulder, elbow, wrist)
cv2.putText(frame, f"Left Elbow: {int(angle)} deg", (20,40),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,0), 2)
out.write(frame)
frame_count += 1
cap.release()
out.release()
return out_path
# Gradio interface
demo = gr.Interface(
fn=detect_pose_video,
inputs=gr.Video(label="Upload Video"),
outputs=gr.Video(label="Annotated Video"),
title="Human Pose Estimation on Video",
description="Upload a video (max 20 seconds will be processed) and see pose landmarks & joint angles."
)
if __name__ == "__main__":
demo.launch()
|