Spaces:
Sleeping
Sleeping
kerojohan commited on
Commit ·
2efea6e
1
Parent(s): 146f9cc
Show pipeline progress in Gradio UI
Browse files- app.py +10 -2
- bat_tracker/pipeline.py +18 -3
app.py
CHANGED
|
@@ -24,7 +24,8 @@ APP_DESCRIPTION = (
|
|
| 24 |
def _prepare_config(config_file: str | None, work_dir: Path) -> Path:
|
| 25 |
cfg = load_config(config_file)
|
| 26 |
cfg.setdefault("output", {})
|
| 27 |
-
cfg["output"]["progress_enabled"] =
|
|
|
|
| 28 |
|
| 29 |
config_path = work_dir / "space_config.yaml"
|
| 30 |
with config_path.open("w", encoding="utf-8") as handle:
|
|
@@ -50,7 +51,7 @@ def _copy_input_file(src: str, dst_dir: Path) -> Path:
|
|
| 50 |
return dst_path
|
| 51 |
|
| 52 |
|
| 53 |
-
def process_video(video_file: str | None, config_file: str | None):
|
| 54 |
if not video_file:
|
| 55 |
raise gr.Error("Debes subir un video de entrada.")
|
| 56 |
|
|
@@ -62,12 +63,19 @@ def process_video(video_file: str | None, config_file: str | None):
|
|
| 62 |
work_dir.mkdir(parents=True, exist_ok=True)
|
| 63 |
|
| 64 |
try:
|
|
|
|
| 65 |
input_path = _copy_input_file(video_file, work_dir)
|
| 66 |
config_path = _prepare_config(config_file, work_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
meta = run_pipeline(
|
| 68 |
input_video=str(input_path),
|
| 69 |
output_dir=str(output_dir),
|
| 70 |
config_path=str(config_path),
|
|
|
|
| 71 |
)
|
| 72 |
|
| 73 |
outputs = meta.get("outputs", {})
|
|
|
|
| 24 |
def _prepare_config(config_file: str | None, work_dir: Path) -> Path:
|
| 25 |
cfg = load_config(config_file)
|
| 26 |
cfg.setdefault("output", {})
|
| 27 |
+
cfg["output"]["progress_enabled"] = True
|
| 28 |
+
cfg["output"]["progress_step_percent"] = 2
|
| 29 |
|
| 30 |
config_path = work_dir / "space_config.yaml"
|
| 31 |
with config_path.open("w", encoding="utf-8") as handle:
|
|
|
|
| 51 |
return dst_path
|
| 52 |
|
| 53 |
|
| 54 |
+
def process_video(video_file: str | None, config_file: str | None, progress=gr.Progress()):
|
| 55 |
if not video_file:
|
| 56 |
raise gr.Error("Debes subir un video de entrada.")
|
| 57 |
|
|
|
|
| 63 |
work_dir.mkdir(parents=True, exist_ok=True)
|
| 64 |
|
| 65 |
try:
|
| 66 |
+
progress(0, desc="Preparando ejecución")
|
| 67 |
input_path = _copy_input_file(video_file, work_dir)
|
| 68 |
config_path = _prepare_config(config_file, work_dir)
|
| 69 |
+
|
| 70 |
+
def on_pipeline_progress(pct: int, detail: str | None) -> None:
|
| 71 |
+
description = detail or "Procesando"
|
| 72 |
+
progress(min(max(pct / 100.0, 0.0), 1.0), desc=description)
|
| 73 |
+
|
| 74 |
meta = run_pipeline(
|
| 75 |
input_video=str(input_path),
|
| 76 |
output_dir=str(output_dir),
|
| 77 |
config_path=str(config_path),
|
| 78 |
+
progress_callback=on_pipeline_progress,
|
| 79 |
)
|
| 80 |
|
| 81 |
outputs = meta.get("outputs", {})
|
bat_tracker/pipeline.py
CHANGED
|
@@ -9,7 +9,7 @@ from math import ceil
|
|
| 9 |
from math import hypot
|
| 10 |
from pathlib import Path
|
| 11 |
from statistics import mean
|
| 12 |
-
from typing import Dict, List
|
| 13 |
|
| 14 |
import cv2
|
| 15 |
import numpy as np
|
|
@@ -207,12 +207,19 @@ class TemporalBurstGate:
|
|
| 207 |
|
| 208 |
|
| 209 |
class ProgressReporter:
|
| 210 |
-
def __init__(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
self.enabled = bool(enabled) and bool(stages)
|
| 212 |
self.step_percent = max(1, min(100, int(step_percent)))
|
| 213 |
self._next_threshold = self.step_percent
|
| 214 |
self._last_reported = 0
|
| 215 |
self._current_stage = ""
|
|
|
|
| 216 |
|
| 217 |
total_weight = sum(max(0.0, float(weight)) for _, weight in stages)
|
| 218 |
if total_weight <= 0:
|
|
@@ -252,6 +259,8 @@ class ProgressReporter:
|
|
| 252 |
self._emit(pct, detail=detail)
|
| 253 |
|
| 254 |
def _emit(self, pct: int, detail: str | None = None) -> None:
|
|
|
|
|
|
|
| 255 |
if pct < self._next_threshold:
|
| 256 |
return
|
| 257 |
self._last_reported = pct
|
|
@@ -644,7 +653,12 @@ def _export_track_clips(
|
|
| 644 |
return clip_paths
|
| 645 |
|
| 646 |
|
| 647 |
-
def run_pipeline(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 648 |
cfg = load_config(config_path)
|
| 649 |
execution_plan = build_execution_plan(cfg)
|
| 650 |
execution_cfg = cfg.get("execution", {})
|
|
@@ -681,6 +695,7 @@ def run_pipeline(input_video: str, output_dir: str, config_path: str | None = No
|
|
| 681 |
("exports_core", 12.0),
|
| 682 |
("track_clips", 10.0 if export_track_clips_enabled else 0.0),
|
| 683 |
],
|
|
|
|
| 684 |
)
|
| 685 |
|
| 686 |
progress.start_stage("background")
|
|
|
|
| 9 |
from math import hypot
|
| 10 |
from pathlib import Path
|
| 11 |
from statistics import mean
|
| 12 |
+
from typing import Callable, Dict, List
|
| 13 |
|
| 14 |
import cv2
|
| 15 |
import numpy as np
|
|
|
|
| 207 |
|
| 208 |
|
| 209 |
class ProgressReporter:
|
| 210 |
+
def __init__(
|
| 211 |
+
self,
|
| 212 |
+
enabled: bool,
|
| 213 |
+
step_percent: int,
|
| 214 |
+
stages: list[tuple[str, float]],
|
| 215 |
+
callback: Callable[[int, str | None], None] | None = None,
|
| 216 |
+
):
|
| 217 |
self.enabled = bool(enabled) and bool(stages)
|
| 218 |
self.step_percent = max(1, min(100, int(step_percent)))
|
| 219 |
self._next_threshold = self.step_percent
|
| 220 |
self._last_reported = 0
|
| 221 |
self._current_stage = ""
|
| 222 |
+
self._callback = callback
|
| 223 |
|
| 224 |
total_weight = sum(max(0.0, float(weight)) for _, weight in stages)
|
| 225 |
if total_weight <= 0:
|
|
|
|
| 259 |
self._emit(pct, detail=detail)
|
| 260 |
|
| 261 |
def _emit(self, pct: int, detail: str | None = None) -> None:
|
| 262 |
+
if self._callback is not None:
|
| 263 |
+
self._callback(pct, detail or self._current_stage or None)
|
| 264 |
if pct < self._next_threshold:
|
| 265 |
return
|
| 266 |
self._last_reported = pct
|
|
|
|
| 653 |
return clip_paths
|
| 654 |
|
| 655 |
|
| 656 |
+
def run_pipeline(
|
| 657 |
+
input_video: str,
|
| 658 |
+
output_dir: str,
|
| 659 |
+
config_path: str | None = None,
|
| 660 |
+
progress_callback: Callable[[int, str | None], None] | None = None,
|
| 661 |
+
) -> Dict:
|
| 662 |
cfg = load_config(config_path)
|
| 663 |
execution_plan = build_execution_plan(cfg)
|
| 664 |
execution_cfg = cfg.get("execution", {})
|
|
|
|
| 695 |
("exports_core", 12.0),
|
| 696 |
("track_clips", 10.0 if export_track_clips_enabled else 0.0),
|
| 697 |
],
|
| 698 |
+
callback=progress_callback,
|
| 699 |
)
|
| 700 |
|
| 701 |
progress.start_stage("background")
|