cheenchan commited on
Commit
cf9e8f3
·
1 Parent(s): 45f025a

Show catalog gallery immediately after video upload

Browse files
frame_extraction/src/frame_extraction/app.py CHANGED
@@ -51,11 +51,12 @@ def summarize_catalog(catalog_path: Path) -> Tuple[str, list[dict[str, Any]], li
51
  return message, index, gallery
52
 
53
 
54
- def build_catalog_from_video(file: gr.FileData) -> tuple[str | None, str, list[dict[str, Any]], list[list[str]]]:
55
- if file is None:
56
  raise gr.Error("Please upload a source video first.")
57
 
58
  ensure_output_dirs()
 
59
  run_id = uuid.uuid4().hex[:8]
60
  video_dir = OUTPUT_DIR / "videos"
61
  video_path = video_dir / f"{run_id}_{Path(file.name).name}"
@@ -65,14 +66,17 @@ def build_catalog_from_video(file: gr.FileData) -> tuple[str | None, str, list[d
65
  cfg = CatalogConfig(video_path=video_path, output_dir=catalog_dir)
66
  catalog_path = build_catalog(cfg)
67
  message, index, gallery = summarize_catalog(catalog_path)
68
- return str(catalog_path), message, index, gallery
 
 
 
69
 
70
 
71
- def predict_from_arrays(arrays: list[np.ndarray], catalog_path: str | None) -> tuple[list[dict[str, Any]], list[list[str]]]:
72
  if not catalog_path:
73
  raise gr.Error("Catalog not ready yet. Upload a video first.")
74
 
75
- if not arrays:
76
  raise gr.Error("Please upload at least one frame.")
77
 
78
  ensure_output_dirs()
@@ -80,7 +84,10 @@ def predict_from_arrays(arrays: list[np.ndarray], catalog_path: str | None) -> t
80
  frames_dir = OUTPUT_DIR / "frames" / run_id
81
  frames_dir.mkdir(parents=True, exist_ok=True)
82
 
83
- for idx, array in enumerate(arrays):
 
 
 
84
  Image.fromarray(array).save(frames_dir / f"upload_{idx:03d}.png")
85
 
86
  output_path = OUTPUT_DIR / f"matches_{run_id}.json"
@@ -119,7 +126,11 @@ def build_interface() -> gr.Blocks:
119
  catalog_json = gr.JSON(label="Character Index", value=initial_index)
120
  catalog_gallery = gr.Gallery(label="Catalog Characters", columns=4, value=initial_gallery)
121
 
122
- video_upload = gr.File(label="Source video", file_types=["video"], height="auto")
 
 
 
 
123
  frame_upload = gr.UploadButton(
124
  label="Upload frames",
125
  file_types=["image"],
@@ -129,16 +140,17 @@ def build_interface() -> gr.Blocks:
129
  matches_json = gr.JSON(label="Matches")
130
  match_gallery = gr.Gallery(label="Matched Characters", columns=3)
131
 
132
- def on_video_upload(file: gr.FileData) -> tuple[str | None, str, list[dict[str, Any]], list[list[str]]]:
133
- return build_catalog_from_video(file)
134
-
135
- video_upload.change(on_video_upload, inputs=video_upload, outputs=[catalog_state, status_box, catalog_json, catalog_gallery])
136
-
137
- def on_frames_upload(files: list[gr.FileData], catalog_path: str | None) -> tuple[list[dict[str, Any]], list[list[str]]]:
138
- arrays = [np.array(Image.open(file.name).convert("RGB")) for file in files]
139
- return predict_from_arrays(arrays, catalog_path)
140
 
141
- frame_upload.upload(on_frames_upload, inputs=[frame_upload, catalog_state], outputs=[matches_json, match_gallery])
 
 
 
 
142
  return demo
143
 
144
 
 
51
  return message, index, gallery
52
 
53
 
54
+ def build_catalog_from_video(files: list[gr.FileData]) -> tuple[str | None, str, list[dict[str, Any]], list[list[str]], list[dict[str, Any]], list[list[str]]]:
55
+ if not files:
56
  raise gr.Error("Please upload a source video first.")
57
 
58
  ensure_output_dirs()
59
+ file = files[0]
60
  run_id = uuid.uuid4().hex[:8]
61
  video_dir = OUTPUT_DIR / "videos"
62
  video_path = video_dir / f"{run_id}_{Path(file.name).name}"
 
66
  cfg = CatalogConfig(video_path=video_path, output_dir=catalog_dir)
67
  catalog_path = build_catalog(cfg)
68
  message, index, gallery = summarize_catalog(catalog_path)
69
+ # When a new catalog is generated, clear existing matches display
70
+ empty_matches: list[dict[str, Any]] = []
71
+ empty_gallery: list[list[str]] = []
72
+ return str(catalog_path), message, index, gallery, empty_matches, empty_gallery
73
 
74
 
75
+ def predict_from_arrays(files: list[gr.FileData], catalog_path: str | None) -> tuple[list[dict[str, Any]], list[list[str]]]:
76
  if not catalog_path:
77
  raise gr.Error("Catalog not ready yet. Upload a video first.")
78
 
79
+ if not files:
80
  raise gr.Error("Please upload at least one frame.")
81
 
82
  ensure_output_dirs()
 
84
  frames_dir = OUTPUT_DIR / "frames" / run_id
85
  frames_dir.mkdir(parents=True, exist_ok=True)
86
 
87
+ arrays: list[np.ndarray] = []
88
+ for idx, file in enumerate(files):
89
+ array = np.array(Image.open(file.name).convert("RGB"))
90
+ arrays.append(array)
91
  Image.fromarray(array).save(frames_dir / f"upload_{idx:03d}.png")
92
 
93
  output_path = OUTPUT_DIR / f"matches_{run_id}.json"
 
126
  catalog_json = gr.JSON(label="Character Index", value=initial_index)
127
  catalog_gallery = gr.Gallery(label="Catalog Characters", columns=4, value=initial_gallery)
128
 
129
+ video_upload = gr.UploadButton(
130
+ label="Upload source video",
131
+ file_types=["video"],
132
+ file_count="single",
133
+ )
134
  frame_upload = gr.UploadButton(
135
  label="Upload frames",
136
  file_types=["image"],
 
140
  matches_json = gr.JSON(label="Matches")
141
  match_gallery = gr.Gallery(label="Matched Characters", columns=3)
142
 
143
+ video_upload.upload(
144
+ build_catalog_from_video,
145
+ inputs=video_upload,
146
+ outputs=[catalog_state, status_box, catalog_json, catalog_gallery, matches_json, match_gallery],
147
+ )
 
 
 
148
 
149
+ frame_upload.upload(
150
+ predict_from_arrays,
151
+ inputs=[frame_upload, catalog_state],
152
+ outputs=[matches_json, match_gallery],
153
+ )
154
  return demo
155
 
156