Optimizer (scripts/optimizer/): replay.py runs the real C++ tracker/matcher/ scene_tracker chain over a dumped-embeddings HDF5 via sae_kpn, so a threshold sweep never re-decodes video or re-embeds faces. optimize.py drives scipy's differential_evolution over the knob space, with DE-level parallelism (multiple population candidates evaluated concurrently via a ThreadPoolExecutor) on top of per-film replay parallelism. second_score.py is the per-second X-Ray scoring metric (TPI/FPI/FN, out-of-cast misID weighted 10x, fair recall masked to gallery-known cast) that superseded an earlier scene-union metric. dump_error_frames.py / dump_scene_montage.py extract annotated video frames (bounding boxes, TPI/FPI/FN captions, onscreen-vs-offscreen split) for visual review of a replay against ground truth. Gallery utilities: cast_restrict.py, gallery_membership.py, fetch_missing_actors.py, reembed_gallery.py. scripts/validation/: X-Ray ground-truth loading and provider-agnostic identity matching (identity.py's keys_for — an actor is the union of every id we can derive, since pipeline output and ground truth don't share one id space). scripts/artifacts/: push/pull scripts for the Gitea generic package registry — galleries, montage frames, and experiment data (manifests/trajectories/results) are pushed there instead of committed, since none are needed to run the app, only benchmarks. Versioned by git short-SHA. scripts/docs/: MkDocs site build (build_site.sh) and the calibration-curve comparison chart (calibration_chart.py, matplotlib, reads each gallery's embedded calibration). Gallery-building scripts (make_jellyfin_gallery.py, make_gallery.py, filter_gallery.py, run_from_jellyfin.py, movienet_eval.py, movienet_prep.py, sae_gallery.py) updated to read/write HDF5 galleries exclusively, matching the engine-side format switch. run_from_jellyfin.py and the optimizer no longer carry movie source paths in shared manifests (some source filenames include scene-release tags) — resolved locally via a gitignored file-lut.json instead.
89 lines
3.9 KiB
Bash
Executable File
89 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Download ONNX models required by scene_analyze and build_gallery.
|
|
# Run from the project root: bash scripts/download_models.sh
|
|
|
|
set -euo pipefail
|
|
|
|
MODELS_DIR="${1:-models}"
|
|
mkdir -p "$MODELS_DIR"
|
|
|
|
# ── YuNet face detection ──────────────────────────────────────────────────────
|
|
YUNET_URL="https://github.com/opencv/opencv_zoo/raw/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx"
|
|
YUNET_FILE="$MODELS_DIR/face_detection_yunet_2023mar.onnx"
|
|
if [ ! -f "$YUNET_FILE" ]; then
|
|
echo "Downloading YuNet…"
|
|
curl -L "$YUNET_URL" -o "$YUNET_FILE"
|
|
else
|
|
echo "YuNet already present: $YUNET_FILE"
|
|
fi
|
|
|
|
# ── ArcFace face recognition (buffalo_l / w600k_r50) ─────────────────────────
|
|
# This model is part of InsightFace's buffalo_l pack.
|
|
# We download and unpack only the recognition model.
|
|
ARCFACE_FILE="$MODELS_DIR/arcface_w600k_r50.onnx"
|
|
if [ ! -f "$ARCFACE_FILE" ]; then
|
|
echo "Downloading ArcFace (buffalo_l)…"
|
|
TMP_ZIP=$(mktemp /tmp/buffalo_l.XXXXXX.zip)
|
|
curl -L "https://github.com/deepinsight/insightface/releases/download/v0.7/buffalo_l.zip" \
|
|
-o "$TMP_ZIP"
|
|
# The zip contains: 1k3d68.onnx 2d106det.onnx det_10g.onnx genderage.onnx w600k_r50.onnx
|
|
unzip -jo "$TMP_ZIP" "w600k_r50.onnx" -d "$MODELS_DIR"
|
|
mv "$MODELS_DIR/w600k_r50.onnx" "$ARCFACE_FILE"
|
|
rm "$TMP_ZIP"
|
|
else
|
|
echo "ArcFace already present: $ARCFACE_FILE"
|
|
fi
|
|
|
|
# ── ArcFace face recognition (buffalo_s / w600k_mbf — MobileFaceNet) ─────────
|
|
# Lighter backbone (13 MB vs 174 MB for R50) — same 512-dim output, faster inference.
|
|
ARCFACE_MBF_FILE="$MODELS_DIR/arcface_w600k_mbf.onnx"
|
|
if [ ! -f "$ARCFACE_MBF_FILE" ]; then
|
|
echo "Downloading ArcFace MobileFaceNet (buffalo_s)…"
|
|
TMP_ZIP=$(mktemp /tmp/buffalo_s.XXXXXX.zip)
|
|
curl -L "https://github.com/deepinsight/insightface/releases/download/v0.7/buffalo_s.zip" \
|
|
-o "$TMP_ZIP"
|
|
unzip -jo "$TMP_ZIP" "w600k_mbf.onnx" -d "$MODELS_DIR"
|
|
mv "$MODELS_DIR/w600k_mbf.onnx" "$ARCFACE_MBF_FILE"
|
|
rm "$TMP_ZIP"
|
|
else
|
|
echo "ArcFace MBF already present: $ARCFACE_MBF_FILE"
|
|
fi
|
|
|
|
# ── SCRFD-500MF face detection (InsightFace buffalo_sc) ───────────────────────
|
|
# buffalo_sc.zip contains det_500m.onnx (SCRFD-500MF with 5 keypoints).
|
|
# If the unzip fails (file not found in archive), download manually from:
|
|
# https://huggingface.co/deepinsight/insightface/resolve/main/models/buffalo_sc/det_500m.onnx
|
|
SCRFD_FILE="$MODELS_DIR/scrfd_500m_bnkps.onnx"
|
|
if [ ! -f "$SCRFD_FILE" ]; then
|
|
echo "Downloading SCRFD-500MF (buffalo_sc)…"
|
|
TMP_ZIP=$(mktemp /tmp/buffalo_sc.XXXXXX.zip)
|
|
curl -L "https://github.com/deepinsight/insightface/releases/download/v0.7/buffalo_sc.zip" \
|
|
-o "$TMP_ZIP"
|
|
unzip -jo "$TMP_ZIP" "det_500m.onnx" -d "$MODELS_DIR"
|
|
mv "$MODELS_DIR/det_500m.onnx" "$SCRFD_FILE"
|
|
rm "$TMP_ZIP"
|
|
else
|
|
echo "SCRFD-500MF already present: $SCRFD_FILE"
|
|
fi
|
|
|
|
# ── TransNetV2 shot-boundary detection (scene detector, opt-in) ───────────────
|
|
# ONNX export (elya5/transnetv2, MIT). Fixed input 1x100x27x48x3 (RGB 0-255),
|
|
# primary output "534" = per-frame boundary logits. Used only with --scene-detect.
|
|
SCENE_FILE="$MODELS_DIR/transnetv2.onnx"
|
|
SCENE_SHA="c4d54a682bace32f25136ef83ca2c9d403e8f8193775efeb995172a0d95a8e0c"
|
|
if [ ! -f "$SCENE_FILE" ]; then
|
|
echo "Downloading TransNetV2…"
|
|
curl -L "https://huggingface.co/elya5/transnetv2/resolve/main/transnetv2.onnx" \
|
|
-o "$SCENE_FILE"
|
|
if command -v sha256sum >/dev/null; then
|
|
echo "$SCENE_SHA $SCENE_FILE" | sha256sum -c - \
|
|
|| echo "WARNING: TransNetV2 sha256 mismatch (upstream may have changed)"
|
|
fi
|
|
else
|
|
echo "TransNetV2 already present: $SCENE_FILE"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Models ready in $MODELS_DIR/:"
|
|
ls -lh "$MODELS_DIR"
|