AccessPath / tools /audit_accessibility_3d_candidate.py
anonymous-accesspath's picture
Audited anonymous-review AccessPath release
2f382c4 verified
Raw
History Blame Contribute Delete
3.49 kB
#!/usr/bin/env python3
"""Write an auditable preflight and multiview verification report for one run."""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
import numpy as np
from PIL import Image
PROJECT_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(PROJECT_ROOT))
from accessibilityamodal.verification import build_verification # noqa: E402
def read_json(path: Path) -> dict:
return json.loads(path.read_text(encoding="utf-8"))
def read_mask(path: Path) -> np.ndarray:
mask = np.asarray(Image.open(path).convert("L")) > 127
return mask
def find_sam_quality(run_dir: Path, sample_id: str) -> dict | None:
for root in (run_dir / "01_sam3", run_dir / "01_sam3_retry"):
path = root / "samples" / sample_id / "quality.json"
if path.is_file():
return read_json(path)
return None
def find_reviewed_visible_metadata(run_dir: Path) -> dict | None:
path = run_dir / "01_reviewed_visible" / "metadata.json"
return read_json(path) if path.is_file() else None
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--run-dir", required=True)
parser.add_argument("--sample-id", required=True)
parser.add_argument("--category", required=True, choices=["curb_cut", "ramp", "stairs", "tactile_paving", "walkway"])
parser.add_argument("--output", default=None)
parser.add_argument("--preflight-only", action="store_true")
parser.add_argument("--print-decision", action="store_true")
args = parser.parse_args()
run_dir = Path(args.run_dir).expanduser().resolve()
masks_dir = run_dir / "02_masks"
visible = read_mask(masks_dir / "target_visible.png")
amodal = read_mask(masks_dir / "target_amodal.png")
hidden = read_mask(masks_dir / "hidden.png")
obstacle = read_mask(masks_dir / "obstacle.png")
geometry_path = run_dir / "04_3d_completion" / "geometry" / "geometry_manifest.json"
geometry = None if args.preflight_only or not geometry_path.is_file() else read_json(geometry_path)
learned_dir = None
if not args.preflight_only:
learned_candidates = (
run_dir / "accessibility3d",
run_dir / "04_3d_completion" / "visual_candidate",
)
learned_dir = next(
(candidate for candidate in learned_candidates if candidate.is_dir()),
learned_candidates[0],
)
report = build_verification(
sample_id=args.sample_id,
category=args.category,
visible_mask=visible,
amodal_mask=amodal,
hidden_mask=hidden,
obstacle_mask=obstacle,
sam3_quality=find_sam_quality(run_dir, args.sample_id),
reviewed_visible_metadata=find_reviewed_visible_metadata(run_dir),
geometry_manifest=geometry,
learned_dir=learned_dir,
)
output = (
Path(args.output).expanduser().resolve()
if args.output
else run_dir / "05_quality_checks" / "verification.json"
)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8")
if args.print_decision:
print(report["decision"])
else:
print(json.dumps({"output": str(output), "decision": report["decision"], "gate": report["gate"]}, ensure_ascii=False))
return 0
if __name__ == "__main__":
raise SystemExit(main())