ashu1069 commited on
Commit
624e18c
·
1 Parent(s): 027e62c
Files changed (1) hide show
  1. app.py +54 -38
app.py CHANGED
@@ -181,55 +181,49 @@ class VideoAnnotator:
181
  # Save current annotations before moving to next video
182
  save_status = "No annotations provided to save." # Default status
183
  if self.video_files:
184
- # --- Start Edit: Check if annotations were actually provided ---
185
- # Check if any annotation was actually selected
186
  annotations_provided = any(ann is not None for ann in current_annotations)
187
-
188
  if annotations_provided:
189
- save_status = self.save_annotation(*current_annotations) # Pass all, save_annotation filters None
190
  logger.info(f"Save status before moving next: {save_status}")
191
  else:
192
  logger.info("No annotations selected, skipping save before moving next.")
193
- # --- End Edit ---
194
-
195
  # Move to next video
196
  if self.current_video_idx < len(self.video_files) - 1:
197
  self.current_video_idx += 1
198
  logger.info(f"Moving to next video (index: {self.current_video_idx})")
199
- # --- Start Edit: Return save status along with video and cleared annotations ---
200
- return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), save_status
201
  # --- End Edit ---
202
  else:
203
  logger.info("Already at the last video")
204
- # --- Start Edit: Return save status ---
205
  return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), "Already at the last video. " + save_status
206
  # --- End Edit ---
207
-
208
  def prev_video(self, *current_annotations):
209
  # Save current annotations before moving to previous video
210
  save_status = "No annotations provided to save." # Default status
211
  if self.video_files:
212
- # --- Start Edit: Check if annotations were actually provided ---
213
- # Check if any annotation was actually selected
214
  annotations_provided = any(ann is not None for ann in current_annotations)
215
-
216
  if annotations_provided:
217
- save_status = self.save_annotation(*current_annotations) # Pass all, save_annotation filters None
218
  logger.info(f"Save status before moving previous: {save_status}")
219
  else:
220
  logger.info("No annotations selected, skipping save before moving previous.")
221
- # --- End Edit ---
222
 
223
  # Move to previous video
224
  if self.current_video_idx > 0:
225
  self.current_video_idx -= 1
226
  logger.info(f"Moving to previous video (index: {self.current_video_idx})")
227
- # --- Start Edit: Return save status along with video and cleared annotations ---
228
  return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), save_status
229
  # --- End Edit ---
230
  else:
231
  logger.info("Already at the first video")
232
- # --- Start Edit: Return save status ---
233
  return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), "Already at the first video. " + save_status
234
  # --- End Edit ---
235
 
@@ -244,36 +238,52 @@ def create_interface():
244
  with gr.Blocks() as demo:
245
  gr.Markdown("# Cricket Video Annotation Tool")
246
 
 
 
 
 
 
 
 
247
  with gr.Row(): # Main row to hold video and controls side-by-side
248
- with gr.Column(scale=2): # You could also adjust this scale (e.g., scale=2) to make it narrower
249
  video_player = gr.Video(
250
- value=annotator.get_current_video,
251
- label="Current Video",
252
- height=350 # Reduced height from 500 to 400 (adjust as needed)
253
  )
254
- # Status textbox below the video
255
- status_textbox = gr.Textbox(label="Status", interactive=False)
 
 
 
 
256
 
257
- with gr.Column(scale=2): # You could adjust this scale (e.g., scale=3) if you change the video column's scale
258
  annotation_components = []
259
  gr.Markdown("### Annotations") # Header for the annotation section
260
 
261
  # Display annotation radio buttons vertically in this column
262
- # You might still need two columns here if vertical space is tight
263
- # For simplicity, let's try one column first.
264
  for category, options in ANNOTATION_CATEGORIES.items():
265
  radio = gr.Radio(
266
  choices=options,
267
  label=category,
268
- # info=f"Select {category}" # Removing info saves a bit of vertical space
269
  )
270
  annotation_components.append(radio)
271
 
272
- # Buttons below the annotations, within the same column
273
- with gr.Row():
274
- prev_btn = gr.Button("Previous Video")
275
- save_btn = gr.Button("Save Annotations", variant="primary")
276
- next_btn = gr.Button("Next Video")
 
 
 
 
 
 
 
 
277
 
278
  # Initialize with first video and potential annotations (logic remains the same)
279
  current_video = annotator.get_current_video()
@@ -295,25 +305,31 @@ def create_interface():
295
  # A more robust solution might involve a dedicated "load" button or
296
  # returning initial component values from a setup function.
297
 
298
- # Event handlers (ensure outputs match the new layout variables)
299
  save_btn.click(
300
  fn=annotator.save_annotation,
301
  inputs=annotation_components,
302
- outputs=status_textbox # Output to the status textbox defined earlier
 
 
303
  )
304
 
305
  next_btn.click(
306
  fn=annotator.next_video,
307
  inputs=annotation_components,
308
- # Outputs: video, clear all radios, update status
309
- outputs=[video_player] + annotation_components + [status_textbox]
 
 
310
  )
311
 
312
  prev_btn.click(
313
  fn=annotator.prev_video,
314
  inputs=annotation_components,
315
- # Outputs: video, clear all radios, update status
316
- outputs=[video_player] + annotation_components + [status_textbox]
 
 
317
  )
318
 
319
  return demo
 
181
  # Save current annotations before moving to next video
182
  save_status = "No annotations provided to save." # Default status
183
  if self.video_files:
 
 
184
  annotations_provided = any(ann is not None for ann in current_annotations)
 
185
  if annotations_provided:
186
+ save_status = self.save_annotation(*current_annotations)
187
  logger.info(f"Save status before moving next: {save_status}")
188
  else:
189
  logger.info("No annotations selected, skipping save before moving next.")
190
+ save_status = "Skipped saving - no annotations selected."
191
+
192
  # Move to next video
193
  if self.current_video_idx < len(self.video_files) - 1:
194
  self.current_video_idx += 1
195
  logger.info(f"Moving to next video (index: {self.current_video_idx})")
196
+ # --- Start Edit: Return only the save status as the last element ---
197
+ return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), save_status
198
  # --- End Edit ---
199
  else:
200
  logger.info("Already at the last video")
201
+ # --- Start Edit: Return only the save status as the last element ---
202
  return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), "Already at the last video. " + save_status
203
  # --- End Edit ---
204
+
205
  def prev_video(self, *current_annotations):
206
  # Save current annotations before moving to previous video
207
  save_status = "No annotations provided to save." # Default status
208
  if self.video_files:
 
 
209
  annotations_provided = any(ann is not None for ann in current_annotations)
 
210
  if annotations_provided:
211
+ save_status = self.save_annotation(*current_annotations)
212
  logger.info(f"Save status before moving previous: {save_status}")
213
  else:
214
  logger.info("No annotations selected, skipping save before moving previous.")
215
+ save_status = "Skipped saving - no annotations selected."
216
 
217
  # Move to previous video
218
  if self.current_video_idx > 0:
219
  self.current_video_idx -= 1
220
  logger.info(f"Moving to previous video (index: {self.current_video_idx})")
221
+ # --- Start Edit: Return only the save status as the last element ---
222
  return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), save_status
223
  # --- End Edit ---
224
  else:
225
  logger.info("Already at the first video")
226
+ # --- Start Edit: Return only the save status as the last element ---
227
  return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), "Already at the first video. " + save_status
228
  # --- End Edit ---
229
 
 
238
  with gr.Blocks() as demo:
239
  gr.Markdown("# Cricket Video Annotation Tool")
240
 
241
+ # --- Start Edit: Define progress update function ---
242
+ total_categories = len(ANNOTATION_CATEGORIES)
243
+ def update_progress(*annotation_values):
244
+ filled_count = sum(1 for val in annotation_values if val is not None)
245
+ return f"**Progress:** {filled_count} / {total_categories} categories selected"
246
+ # --- End Edit ---
247
+
248
  with gr.Row(): # Main row to hold video and controls side-by-side
249
+ with gr.Column(scale=2): # Column for Video Player and Nav Buttons
250
  video_player = gr.Video(
251
+ value=annotator.get_current_video,
252
+ label="Current Video",
253
+ height=350
254
  )
255
+ # --- Start Edit: Rename status_textbox to status_display ---
256
+ status_display = gr.Textbox(label="Status", interactive=False) # For save/nav messages
257
+ # --- End Edit ---
258
+ with gr.Row():
259
+ prev_btn = gr.Button("Previous Video")
260
+ next_btn = gr.Button("Next Video")
261
 
262
+ with gr.Column(scale=2): # Column for Annotations and Save Button
263
  annotation_components = []
264
  gr.Markdown("### Annotations") # Header for the annotation section
265
 
266
  # Display annotation radio buttons vertically in this column
 
 
267
  for category, options in ANNOTATION_CATEGORIES.items():
268
  radio = gr.Radio(
269
  choices=options,
270
  label=category,
 
271
  )
272
  annotation_components.append(radio)
273
 
274
+ # --- Start Edit: Add Progress Display and attach change listeners ---
275
+ progress_display = gr.Markdown(value=update_progress(*[None]*total_categories)) # Initial progress
276
+
277
+ # Attach change listener to each radio button
278
+ for radio in annotation_components:
279
+ radio.change(
280
+ fn=update_progress,
281
+ inputs=annotation_components,
282
+ outputs=progress_display
283
+ )
284
+ # --- End Edit ---
285
+
286
+ save_btn = gr.Button("Save Annotations", variant="primary")
287
 
288
  # Initialize with first video and potential annotations (logic remains the same)
289
  current_video = annotator.get_current_video()
 
305
  # A more robust solution might involve a dedicated "load" button or
306
  # returning initial component values from a setup function.
307
 
308
+ # Event handlers
309
  save_btn.click(
310
  fn=annotator.save_annotation,
311
  inputs=annotation_components,
312
+ # --- Start Edit: Output to status_display ---
313
+ outputs=status_display
314
+ # --- End Edit ---
315
  )
316
 
317
  next_btn.click(
318
  fn=annotator.next_video,
319
  inputs=annotation_components,
320
+ # --- Start Edit: Output status to status_display. Progress updates via radio changes. ---
321
+ # Outputs: video, clear all radios, update status_display
322
+ outputs=[video_player] + annotation_components + [status_display]
323
+ # --- End Edit ---
324
  )
325
 
326
  prev_btn.click(
327
  fn=annotator.prev_video,
328
  inputs=annotation_components,
329
+ # --- Start Edit: Output status to status_display. Progress updates via radio changes. ---
330
+ # Outputs: video, clear all radios, update status_display
331
+ outputs=[video_player] + annotation_components + [status_display]
332
+ # --- End Edit ---
333
  )
334
 
335
  return demo