#!/usr/bin/env python3 """Build the portable held-out (NV) view indices used by eval_final.py (FB150 + Omni300 only; Toys4K-300 keeps the original evaluate_appforce protocol and has no held-out index). Input: the absolute-path indices written by heldout/prepare_heldout.py (heldout_fb150.json, heldout_omni300.json). Output: heldout_index/{fb150,omni300}.json = {object: [{tag, cam, px, src: "exp"|"heldout", kind: "heldout"|"saved"|"pool", vis?}, ...]} src=exp -> files live in the dataset exp dir (inputs/_.png, renders/_.npz) src=heldout -> files live in the held-out root (data/fb150_heldout.tar, omni pool) No record is filtered here; the visibility threshold (--min-vis) is applied by eval_final.py. """ import argparse, json from pathlib import Path LP = "/lp-dev/jonghoon/mv-mesh" def main(): ap = argparse.ArgumentParser() ap.add_argument("--src-dir", type=Path, default=Path(f"{LP}/.debug/eval_heldout_nv")) ap.add_argument("--out", type=Path, default=Path(__file__).resolve().parent / "heldout_index") a = ap.parse_args() a.out.mkdir(parents=True, exist_ok=True) fb = json.loads((a.src_dir / "heldout_fb150.json").read_text()) fb2 = {o: [dict(tag=r["tag"], cam=r["cam"], vis=r["vis"], px=r["px"], src="heldout", kind="heldout") for r in v] for o, v in fb.items()} om = json.loads((a.src_dir / "heldout_omni300.json").read_text()) om2 = {o: [dict(tag=r["tag"], cam=r["cam"], px=r["px"], src="exp" if r["kind"] == "saved" else "heldout", kind=r["kind"]) for r in v] for o, v in om.items()} for name, d in (("fb150", fb2), ("omni300", om2)): (a.out / f"{name}.json").write_text(json.dumps(d, separators=(",", ":"))) n = [len(v) for v in d.values()] print(name, "objects", len(d), "records", sum(n), "min/obj", min(n)) fbv = [len([r for r in v if r["vis"] >= 0.2]) for v in fb2.values()] print("fb150 vis>=0.20: records", sum(fbv), "min/obj", min(fbv), "objs with 0:", sum(x == 0 for x in fbv)) if __name__ == "__main__": main()