NAAZ1605's picture
Prepare ISL command recognition project
e2d95ed
Raw History Blame Contribute Delete
3.41 kB
#!/usr/bin/env python3
"""
Download the MediaPipe Tasks model bundles used by the extractor.
MediaPipe >= 0.10.18 (and 1.x, which this project runs on) no longer ships the
legacy ``mediapipe.solutions`` API; landmark extraction therefore uses the Tasks
API with explicit ``.task`` bundles.
Usage
-----
python scripts/download_models.py # holistic (default) + pose + hand
python scripts/download_models.py --only holistic
python scripts/download_models.py --check # verify what is already present
"""
from __future__ import annotations
import argparse
import sys
import urllib.request
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import config # noqa: E402
ASSETS_DIR = Path(config.MODELS_DIR) / "mediapipe_assets"
BUNDLES = {
"holistic": "https://storage.googleapis.com/mediapipe-models/holistic_landmarker/"
"holistic_landmarker/float16/1/holistic_landmarker.task",
"pose": "https://storage.googleapis.com/mediapipe-models/pose_landmarker/"
"pose_landmarker_lite/float16/1/pose_landmarker_lite.task",
"hand": "https://storage.googleapis.com/mediapipe-models/hand_landmarker/"
"hand_landmarker/float16/1/hand_landmarker.task",
"pose_full": "https://storage.googleapis.com/mediapipe-models/pose_landmarker/"
"pose_landmarker_full/float16/1/pose_landmarker_full.task",
}
MIN_BYTES = 1_000_000
def fetch(name: str, url: str, force: bool = False) -> Path:
dest = ASSETS_DIR / Path(url).name
if dest.exists() and dest.stat().st_size > MIN_BYTES and not force:
print(f" present {dest.name} ({dest.stat().st_size/1e6:.1f} MB)")
return dest
dest.parent.mkdir(parents=True, exist_ok=True)
print(f" fetch {dest.name} <- {url}")
req = urllib.request.Request(url, headers={"User-Agent": "isl-recognition/1.0"})
with urllib.request.urlopen(req, timeout=300) as r, open(dest, "wb") as f:
while True:
chunk = r.read(1 << 20)
if not chunk:
break
f.write(chunk)
size = dest.stat().st_size
if size < MIN_BYTES:
raise RuntimeError(f"{dest.name} looks truncated ({size} bytes)")
print(f" saved {dest.name} ({size/1e6:.1f} MB)")
return dest
def main(argv=None) -> int:
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("--only", choices=list(BUNDLES), default=None)
ap.add_argument("--check", action="store_true")
ap.add_argument("--force", action="store_true")
args = ap.parse_args(argv)
targets = {args.only: BUNDLES[args.only]} if args.only else \
{k: v for k, v in BUNDLES.items() if k != "pose_full"}
print(f"MediaPipe assets -> {ASSETS_DIR}")
missing = []
for name, url in targets.items():
path = ASSETS_DIR / Path(url).name
if args.check:
ok = path.exists() and path.stat().st_size > MIN_BYTES
print(f" {'OK ' if ok else 'MISSING'} {path.name}")
if not ok:
missing.append(name)
else:
fetch(name, url, force=args.force)
if args.check and missing:
print(f"\nRun `python scripts/download_models.py --only {missing[0]}` to fetch the missing bundle(s).")
return 0
if __name__ == "__main__":
raise SystemExit(main())