James040 commited on
Commit
a59a9fc
·
verified ·
1 Parent(s): 2ccad33

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -0
app.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import mediapipe as mp
3
+ import numpy as np
4
+ import gradio as gr
5
+ from moviepy import VideoFileClip
6
+ import os
7
+
8
+ # Initialize MediaPipe Pose
9
+ mp_pose = mp.solutions.pose
10
+ mp_drawing = mp.solutions.drawing_utils
11
+
12
+ # Create "Meaty" drawing specs for EbSynth
13
+ # High thickness (10) and larger circles (15) for better pixel tracking
14
+ MEATY_CONNECTIONS = mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=10, circle_radius=5)
15
+ MEATY_JOINTS = mp_drawing.DrawingSpec(color=(255, 255, 255), thickness=12, circle_radius=15)
16
+
17
+ def extract_pose(video_path):
18
+ if video_path is None:
19
+ return None
20
+
21
+ # 1. Load Video
22
+ cap = cv2.VideoCapture(video_path)
23
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
24
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
25
+ fps = cap.get(cv2.CAP_PROP_FPS)
26
+
27
+ output_path = "stickman_output.mp4"
28
+ temp_output = "temp_no_audio.mp4"
29
+
30
+ # Define Video Writer
31
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
32
+ out = cv2.VideoWriter(temp_output, fourcc, fps, (width, height))
33
+
34
+ with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5, model_complexity=1) as pose:
35
+ while cap.isOpened():
36
+ ret, frame = cap.read()
37
+ if not ret:
38
+ break
39
+
40
+ # Convert to RGB for MediaPipe
41
+ rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
42
+ results = pose.process(rgb_frame)
43
+
44
+ # Create Black Canvas (The "Clear" Background)
45
+ canvas = np.zeros((height, width, 3), dtype=np.uint8)
46
+
47
+ # Draw Meaty Stickman
48
+ if results.pose_landmarks:
49
+ mp_drawing.draw_landmarks(
50
+ canvas,
51
+ results.pose_landmarks,
52
+ mp_pose.POSE_CONNECTIONS,
53
+ landmark_drawing_spec=MEATY_JOINTS,
54
+ connection_drawing_spec=MEATY_CONNECTIONS
55
+ )
56
+
57
+ out.write(canvas)
58
+
59
+ cap.release()
60
+ out.release()
61
+
62
+ # 2. Merge Original Audio back using MoviePy v2.x syntax
63
+ try:
64
+ original_clip = VideoFileClip(video_path)
65
+ stickman_clip = VideoFileClip(temp_output)
66
+
67
+ # New MoviePy v2.x method: with_audio instead of set_audio
68
+ final_video = stickman_clip.with_audio(original_clip.audio)
69
+ final_video.write_videofile(output_path, codec="libx264", audio_codec="aac")
70
+
71
+ return output_path
72
+ except Exception as e:
73
+ print(f"Audio merge failed: {e}")
74
+ return temp_output # Fallback to silent video
75
+
76
+ # Gradio UI
77
+ interface = gr.Interface(
78
+ fn=extract_pose,
79
+ inputs=gr.Video(label="Upload Dancing Clip (15-30s)"),
80
+ outputs=gr.Video(label="Meaty Stickman Output"),
81
+ title="Pose-to-Stickman Extractor",
82
+ description="Extracts high-thickness pose data for EbSynth & Motion Transfer."
83
+ )
84
+
85
+ if __name__ == "__main__":
86
+ interface.launch()