srivatsavdamaraju commited on
Commit
39421c7
·
verified ·
1 Parent(s): 41802ba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -41
app.py CHANGED
@@ -2,65 +2,87 @@ import gradio as gr
2
  import cv2
3
  import os
4
  import uuid
5
- import mediapipe as mp
6
- import pandas as pd
7
  import threading
8
  import time
 
 
9
 
10
- # Setup
11
  OUTPUT_DIR = "captured_frames"
12
  os.makedirs(OUTPUT_DIR, exist_ok=True)
13
  df = pd.DataFrame(columns=["filename", "caption", "pose_coords"])
14
 
15
  pose = mp.solutions.pose.Pose()
 
16
  state = {
17
- "video_path": None,
18
  "cap": None,
19
  "frame": None,
20
  "play": False,
21
- "thread": None
22
  }
23
 
 
24
  def load_video(video_file):
25
- if state["cap"]:
26
- state["cap"].release()
27
- state["video_path"] = video_file.name
28
- state["cap"] = cv2.VideoCapture(state["video_path"])
29
- state["play"] = False
30
- return "Video loaded. Use play/pause to navigate."
31
-
 
 
 
 
 
 
 
 
 
 
 
32
  def play_video():
33
- def play():
34
- while state["cap"].isOpened() and state["play"]:
 
 
 
 
35
  ret, frame = state["cap"].read()
36
  if not ret:
 
37
  break
38
  state["frame"] = frame
39
- time.sleep(0.1) # ~10 FPS
40
 
41
- state["play"] = True
42
- state["thread"] = threading.Thread(target=play)
43
- state["thread"].start()
44
- return "Playing video..."
45
 
 
46
  def pause_video():
47
  state["play"] = False
48
- return "Video paused."
49
 
 
50
  def show_frame():
51
  if state["frame"] is not None:
52
  return state["frame"][:, :, ::-1] # BGR to RGB
53
  return None
54
 
 
55
  def capture_frame(caption):
56
  if state["frame"] is None:
57
- return "No frame to capture.", None
 
 
 
58
 
59
  frame = state["frame"]
60
  filename = f"{uuid.uuid4().hex[:8]}.jpg"
61
  path = os.path.join(OUTPUT_DIR, filename)
62
  cv2.imwrite(path, frame)
63
 
 
64
  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
65
  results = pose.process(frame_rgb)
66
 
@@ -76,13 +98,15 @@ def capture_frame(caption):
76
  "pose_coords": coords
77
  }])], ignore_index=True)
78
 
79
- return f"Frame captured: {filename}", frame[:, :, ::-1]
80
 
 
81
  def download_csv():
82
- csv_path = os.path.join(OUTPUT_DIR, "pose_dataset.csv")
83
- df.to_csv(csv_path, index=False)
84
- return csv_path
85
 
 
86
  def reset_all():
87
  df.drop(df.index, inplace=True)
88
  for f in os.listdir(OUTPUT_DIR):
@@ -90,36 +114,38 @@ def reset_all():
90
  if state["cap"]:
91
  state["cap"].release()
92
  state.update({"video_path": None, "cap": None, "frame": None, "play": False})
93
- return "App reset.", None
94
 
 
95
  with gr.Blocks() as app:
96
- gr.Markdown("## 🏹 Archery Dataset Tool (Play, Pause, Pose + Annotation)")
97
 
98
- video_input = gr.Video(label="Upload Video")
99
- load_btn = gr.Button("Load Video")
 
100
 
101
  with gr.Row():
102
  play_btn = gr.Button("▶️ Play")
103
  pause_btn = gr.Button("⏸️ Pause")
104
- show_btn = gr.Button("🔁 Show Current Frame")
105
 
106
- image_box = gr.Image(label="Current Frame")
107
  caption_input = gr.Textbox(label="Caption")
108
- capture_btn = gr.Button("📸 Capture & Annotate Frame")
109
-
110
- download_btn = gr.Button("📥 Download CSV")
111
- csv_file = gr.File(label="Pose Dataset CSV")
112
 
113
- reset_btn = gr.Button("🔄 Reset")
114
- status = gr.Textbox(label="Status")
 
 
 
115
 
116
- # Event handlers
117
  load_btn.click(load_video, inputs=video_input, outputs=status)
118
  play_btn.click(play_video, outputs=status)
119
  pause_btn.click(pause_video, outputs=status)
120
- show_btn.click(show_frame, outputs=image_box)
121
- capture_btn.click(capture_frame, inputs=caption_input, outputs=[status, image_box])
122
  download_btn.click(download_csv, outputs=csv_file)
123
- reset_btn.click(reset_all, outputs=[status, image_box])
124
 
125
  app.launch()
 
2
  import cv2
3
  import os
4
  import uuid
 
 
5
  import threading
6
  import time
7
+ import mediapipe as mp
8
+ import pandas as pd
9
 
10
+ # === Setup ===
11
  OUTPUT_DIR = "captured_frames"
12
  os.makedirs(OUTPUT_DIR, exist_ok=True)
13
  df = pd.DataFrame(columns=["filename", "caption", "pose_coords"])
14
 
15
  pose = mp.solutions.pose.Pose()
16
+
17
  state = {
 
18
  "cap": None,
19
  "frame": None,
20
  "play": False,
21
+ "video_path": None
22
  }
23
 
24
+ # === Load Video ===
25
  def load_video(video_file):
26
+ try:
27
+ if hasattr(video_file, "name"):
28
+ video_path = video_file.name
29
+ else:
30
+ video_path = video_file
31
+ state["video_path"] = video_path
32
+
33
+ if state["cap"]:
34
+ state["cap"].release()
35
+
36
+ state["cap"] = cv2.VideoCapture(video_path)
37
+ state["frame"] = None
38
+ state["play"] = False
39
+ return "✅ Video loaded successfully!"
40
+ except Exception as e:
41
+ return f"❌ Error loading video: {e}"
42
+
43
+ # === Play video in background ===
44
  def play_video():
45
+ if not state["cap"]:
46
+ return "⚠️ Load a video first."
47
+ state["play"] = True
48
+
49
+ def stream():
50
+ while state["cap"] and state["cap"].isOpened() and state["play"]:
51
  ret, frame = state["cap"].read()
52
  if not ret:
53
+ state["play"] = False
54
  break
55
  state["frame"] = frame
56
+ time.sleep(0.1)
57
 
58
+ threading.Thread(target=stream).start()
59
+ return "▶️ Playing..."
 
 
60
 
61
+ # === Pause playback ===
62
  def pause_video():
63
  state["play"] = False
64
+ return "⏸️ Paused."
65
 
66
+ # === Show current frame ===
67
  def show_frame():
68
  if state["frame"] is not None:
69
  return state["frame"][:, :, ::-1] # BGR to RGB
70
  return None
71
 
72
+ # === Capture frame (auto-pause) ===
73
  def capture_frame(caption):
74
  if state["frame"] is None:
75
+ return "⚠️ No frame to capture.", None
76
+
77
+ # Auto-pause video
78
+ state["play"] = False
79
 
80
  frame = state["frame"]
81
  filename = f"{uuid.uuid4().hex[:8]}.jpg"
82
  path = os.path.join(OUTPUT_DIR, filename)
83
  cv2.imwrite(path, frame)
84
 
85
+ # Pose estimation
86
  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
87
  results = pose.process(frame_rgb)
88
 
 
98
  "pose_coords": coords
99
  }])], ignore_index=True)
100
 
101
+ return f" Captured & paused: {filename}", frame[:, :, ::-1]
102
 
103
+ # === Download CSV ===
104
  def download_csv():
105
+ path = os.path.join(OUTPUT_DIR, "pose_dataset.csv")
106
+ df.to_csv(path, index=False)
107
+ return path
108
 
109
+ # === Reset all ===
110
  def reset_all():
111
  df.drop(df.index, inplace=True)
112
  for f in os.listdir(OUTPUT_DIR):
 
114
  if state["cap"]:
115
  state["cap"].release()
116
  state.update({"video_path": None, "cap": None, "frame": None, "play": False})
117
+ return "🔁 Reset done.", None
118
 
119
+ # === UI ===
120
  with gr.Blocks() as app:
121
+ gr.Markdown("## 🏹 Archery Pose Dataset Tool (Auto-Pause on Capture)")
122
 
123
+ video_input = gr.Video(label="🎞️ Upload Video")
124
+ load_btn = gr.Button("📂 Load Video")
125
+ status = gr.Textbox(label="Status")
126
 
127
  with gr.Row():
128
  play_btn = gr.Button("▶️ Play")
129
  pause_btn = gr.Button("⏸️ Pause")
130
+ show_btn = gr.Button("🖼️ Show Current Frame")
131
 
132
+ image_output = gr.Image(label="Current Frame")
133
  caption_input = gr.Textbox(label="Caption")
134
+ capture_btn = gr.Button("📸 Capture & Pause")
 
 
 
135
 
136
+ with gr.Row():
137
+ download_btn = gr.Button("📥 Download CSV")
138
+ reset_btn = gr.Button("🔄 Reset")
139
+
140
+ csv_file = gr.File(label="📄 Dataset CSV")
141
 
142
+ # Bind actions
143
  load_btn.click(load_video, inputs=video_input, outputs=status)
144
  play_btn.click(play_video, outputs=status)
145
  pause_btn.click(pause_video, outputs=status)
146
+ show_btn.click(show_frame, outputs=image_output)
147
+ capture_btn.click(capture_frame, inputs=caption_input, outputs=[status, image_output])
148
  download_btn.click(download_csv, outputs=csv_file)
149
+ reset_btn.click(reset_all, outputs=[status, image_output])
150
 
151
  app.launch()