beta3 commited on
Commit
38bdb24
·
verified ·
1 Parent(s): abdfcac

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -0
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import mediapipe as mp
4
+ import numpy as np
5
+ import tempfile
6
+ import warnings
7
+ import gradio as gr
8
+
9
+ # --- Silence unnecessary logs and warnings ---
10
+ os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
11
+ os.environ['GLOG_minloglevel'] = '2'
12
+ warnings.filterwarnings("ignore", category=UserWarning)
13
+ warnings.filterwarnings("ignore", message="SymbolDatabase.GetPrototype")
14
+
15
+ # --- Main processing function ---
16
+ def process_pose(video_path, mode, min_det_conf, min_track_conf, progress=gr.Progress()):
17
+ try:
18
+ progress(0, desc="Initializing pose model...")
19
+ mp_drawing = mp.solutions.drawing_utils
20
+ mp_pose = mp.solutions.pose
21
+
22
+ # Temporary output file
23
+ temp_dir = tempfile.mkdtemp()
24
+ output_path = os.path.join(temp_dir, "output.mp4")
25
+
26
+ cap = cv2.VideoCapture(video_path)
27
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
28
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
29
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
30
+ fps = cap.get(cv2.CAP_PROP_FPS)
31
+
32
+ if fps == 0 or total_frames == 0:
33
+ raise ValueError("Could not read the video or it is empty.")
34
+
35
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
36
+ out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
37
+
38
+ with mp_pose.Pose(
39
+ min_detection_confidence=min_det_conf,
40
+ min_tracking_confidence=min_track_conf
41
+ ) as pose:
42
+
43
+ frame_idx = 0
44
+ while cap.isOpened():
45
+ ret, frame = cap.read()
46
+ if not ret:
47
+ break
48
+
49
+ frame_idx += 1
50
+ progress(frame_idx / total_frames, desc=f"Processing frame {frame_idx}/{total_frames}")
51
+
52
+ image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
53
+ results = pose.process(image)
54
+ image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
55
+
56
+ if mode == "Pose on original video":
57
+ output_frame = image.copy()
58
+ mp_drawing.draw_landmarks(
59
+ output_frame,
60
+ results.pose_landmarks,
61
+ mp_pose.POSE_CONNECTIONS,
62
+ mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=2),
63
+ mp_drawing.DrawingSpec(color=(245,66,230), thickness=2, circle_radius=2)
64
+ )
65
+
66
+ else: # Pose only (black background)
67
+ mask = np.zeros_like(image)
68
+ mp_drawing.draw_landmarks(
69
+ mask,
70
+ results.pose_landmarks,
71
+ mp_pose.POSE_CONNECTIONS,
72
+ mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=2),
73
+ mp_drawing.DrawingSpec(color=(245,66,230), thickness=2, circle_radius=2)
74
+ )
75
+ output_frame = cv2.addWeighted(np.zeros_like(image), 1, mask, 0.8, 0)
76
+
77
+ out.write(output_frame)
78
+
79
+ cap.release()
80
+ out.release()
81
+ progress(1, desc="Completed ✅")
82
+ return output_path
83
+
84
+ except Exception as e:
85
+ return f"❌ Error during processing: {e}"
86
+
87
+ # --- Custom HTML for warnings and explanations ---
88
+ warning_html = """
89
+ <div style="text-align:center; color:red; font-weight:bold;">
90
+ ⚠️ Reminder: Video must be under 5 MB due to CPU processing time.<br>
91
+ ⚠️ Processing long videos may take a considerable amount of time.
92
+ </div>
93
+ """
94
+
95
+ param_info_html = """
96
+ <div style="border: 2px solid #4CAF50; padding: 10px; border-radius: 8px; margin:10px; background-color:#f9f9f9;">
97
+ <b>Parameters:</b><br>
98
+ - <b>min_detection_confidence:</b> Minimum confidence for the model to detect a pose.<br>
99
+ - <b>min_tracking_confidence:</b> Minimum confidence for the model to track the pose across frames.
100
+ </div>
101
+ """
102
+
103
+ # --- Gradio Interface ---
104
+ iface = gr.Interface(
105
+ fn=process_pose,
106
+ inputs=[
107
+ gr.Video(label="🎥 Upload your video", sources=["upload"], elem_id="video_upload"),
108
+ gr.Radio(
109
+ ["Pose on original video", "Pose only (black background)"],
110
+ label="Output mode",
111
+ value="Pose on original video"
112
+ ),
113
+ gr.Slider(0.0, 1.0, value=0.5, label="min_detection_confidence"),
114
+ gr.Slider(0.0, 1.0, value=0.5, label="min_tracking_confidence"),
115
+ ],
116
+ outputs=gr.Video(label="📦 Processed Video"),
117
+ title="<center>Pose Estimation - MediaPipe (CPU Optimized)</center>",
118
+ description=warning_html + param_info_html,
119
+ )
120
+
121
+ if __name__ == "__main__":
122
+ iface.launch()