tarekziade HF Staff commited on
Commit
c29be10
·
1 Parent(s): e0185ee

extract frame

Browse files
Files changed (1) hide show
  1. indexing/tests/e2e.py +47 -6
indexing/tests/e2e.py CHANGED
@@ -3,14 +3,20 @@ End-to-end test: pulls images and videos from HF datasets, indexes them
3
  with ragstudio, syncs the index to the team-0/ragstudio bucket, then runs
4
  a sample search over each modality.
5
 
 
 
 
6
  Usage:
7
- python tests/e2e.py
8
  """
9
 
 
10
  import os
 
11
  import sys
12
  from pathlib import Path
13
 
 
14
  from huggingface_hub import snapshot_download
15
 
16
  ROOT = Path(__file__).resolve().parent.parent
@@ -21,10 +27,42 @@ VIDEO_DATASET = "team-0/test-videos"
21
 
22
  IMAGE_QUERY = "a person presenting on stage"
23
 
24
- DATA_DIR = ROOT / "tests" / ".cache" / "data"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
 
27
  def main() -> None:
 
 
 
 
28
  DATA_DIR.mkdir(parents=True, exist_ok=True)
29
 
30
  print(f"[1/4] Downloading datasets to {DATA_DIR}")
@@ -51,10 +89,10 @@ def main() -> None:
51
  # at <repo>/index_data/ instead of vanishing with a temp dir.
52
  os.chdir(ROOT)
53
 
54
- print(f"[2/4] Building index from {DATA_DIR}")
55
  from index import build_index
56
 
57
- build_index(DATA_DIR)
58
 
59
  print("[3/4] Syncing index to team-0/ragstudio bucket")
60
  from sync import sync
@@ -63,6 +101,7 @@ def main() -> None:
63
  print("[4/4] Searching")
64
  from searchers import SEARCHERS
65
 
 
66
  image_hits = SEARCHERS["image"](IMAGE_QUERY, top_k=3)
67
  print(f"\n=== image: {IMAGE_QUERY!r} ===")
68
  for s, p in image_hits:
@@ -72,10 +111,12 @@ def main() -> None:
72
  for q in video_queries:
73
  video_hits = SEARCHERS["video"](q, top_k=3)
74
  print(f"\n=== video: {q!r} ===")
75
- for s, p in video_hits:
76
- print(f" {s:.3f} {p}")
 
77
  assert video_hits, f"no video results for {q!r}"
78
 
 
79
  print("\nOK")
80
 
81
 
 
3
  with ragstudio, syncs the index to the team-0/ragstudio bucket, then runs
4
  a sample search over each modality.
5
 
6
+ Both the downloaded datasets and the FAISS index live under tests/.cache/,
7
+ so re-runs reuse them. Pass --force to rebuild the index from scratch.
8
+
9
  Usage:
10
+ python tests/e2e.py [--force]
11
  """
12
 
13
+ import argparse
14
  import os
15
+ import re
16
  import sys
17
  from pathlib import Path
18
 
19
+ import cv2
20
  from huggingface_hub import snapshot_download
21
 
22
  ROOT = Path(__file__).resolve().parent.parent
 
27
 
28
  IMAGE_QUERY = "a person presenting on stage"
29
 
30
+ CACHE_DIR = ROOT / "tests" / ".cache"
31
+ DATA_DIR = CACHE_DIR / "data"
32
+ FRAMES_DIR = CACHE_DIR / "frames"
33
+
34
+ # Video meta entries are formatted by indexers/video.py as "<path> @ <t>s".
35
+ VIDEO_META_RE = re.compile(r"^(.*) @ (\d+\.\d+)s$")
36
+
37
+
38
+ def extract_video_frame(meta: str, out_dir: Path) -> Path:
39
+ m = VIDEO_META_RE.match(meta)
40
+ if not m:
41
+ raise ValueError(f"unexpected video meta format: {meta!r}")
42
+ vpath, t = m.group(1), float(m.group(2))
43
+
44
+ cap = cv2.VideoCapture(vpath)
45
+ fps = cap.get(cv2.CAP_PROP_FPS) or 0
46
+ if fps > 0:
47
+ cap.set(cv2.CAP_PROP_POS_FRAMES, int(round(t * fps)))
48
+ else:
49
+ cap.set(cv2.CAP_PROP_POS_MSEC, t * 1000)
50
+ ok, frame = cap.read()
51
+ cap.release()
52
+ if not ok:
53
+ raise RuntimeError(f"failed to read frame at {t}s from {vpath}")
54
+
55
+ out_dir.mkdir(parents=True, exist_ok=True)
56
+ out_path = out_dir / f"{Path(vpath).stem}_{t:.2f}s.png"
57
+ cv2.imwrite(str(out_path), frame)
58
+ return out_path
59
 
60
 
61
  def main() -> None:
62
+ parser = argparse.ArgumentParser(description=__doc__.strip())
63
+ parser.add_argument("--force", action="store_true", help="rebuild the index even if cached")
64
+ args = parser.parse_args()
65
+
66
  DATA_DIR.mkdir(parents=True, exist_ok=True)
67
 
68
  print(f"[1/4] Downloading datasets to {DATA_DIR}")
 
89
  # at <repo>/index_data/ instead of vanishing with a temp dir.
90
  os.chdir(ROOT)
91
 
92
+ print(f"[2/4] Building index from {DATA_DIR}{' (force)' if args.force else ''}")
93
  from index import build_index
94
 
95
+ build_index(DATA_DIR, force=args.force)
96
 
97
  print("[3/4] Syncing index to team-0/ragstudio bucket")
98
  from sync import sync
 
101
  print("[4/4] Searching")
102
  from searchers import SEARCHERS
103
 
104
+
105
  image_hits = SEARCHERS["image"](IMAGE_QUERY, top_k=3)
106
  print(f"\n=== image: {IMAGE_QUERY!r} ===")
107
  for s, p in image_hits:
 
111
  for q in video_queries:
112
  video_hits = SEARCHERS["video"](q, top_k=3)
113
  print(f"\n=== video: {q!r} ===")
114
+ for s, meta in video_hits:
115
+ frame_path = extract_video_frame(meta, FRAMES_DIR)
116
+ print(f" {s:.3f} {meta} -> {frame_path}")
117
  assert video_hits, f"no video results for {q!r}"
118
 
119
+
120
  print("\nOK")
121
 
122