scripts/download_models.sh

Fetches both ONNX models into ./models/ (git-ignored — see Quickstart):
Downloads the YuNet detector from OpenCV Zoo and the ArcFace embedder (w600k_r50.onnx) from InsightFace’s buffalo_l release, extracting just that one file from the release zip. Prints the resolved paths and a one-line summary of the preprocessing contract (112×112 RGB, (x-127.5)/127.5, 512-d L2-normalized output) when done.

scripts/run_similarity_test.py

A Python re-implementation of the exact production pipeline — detect (640px-capped) → align (ArcFace template) → normalize → embed → L2-normalize → cosine similarity — used to validate the C++ service’s behavior without needing a full build. This is how every claim in Models was actually checked.
What it does:
  1. Scans scripts/test_images/ for usable images (.png, .jpg, .jpeg; auto-skips raw .heic/.HEIC files in favor of a <name>_converted.png sibling, since OpenCV can’t decode HEIC directly — see the HEIC conversion note below).
  2. Runs each image through cv2.FaceDetectorYN at the same detectorScoreThreshold=0.8 the production service uses, detecting on a 640px-longest-side copy exactly like InferenceEngine::detectFaces.
  3. Aligns with the same 5-point ArcFace template as FaceAligner, and writes the aligned 112×112 crop to scripts/test_images_aligned/ — useful for visually sanity-checking alignment quality, which is how the full-resolution detection bug was originally caught (garbage detections produce visibly wrong crops before they produce wrong numbers).
  4. Embeds with the exact same normalization as InferenceEngine::embedAlignedFace ((x-127.5)/127.5, RGB, L2-normalized output).
  5. Prints every pairwise cosine similarity across all discovered images, sorted descending, plus summary stats (n, mean, std, min, max).
scripts/test_images/ and scripts/test_images_aligned/ are git-ignored — they’re personal test photos, not fixtures meant to ship with the repo. Populate test_images/ yourself with a handful of same-person and different-person photos before running this script.

HEIC images

macOS Photos exports as HEIC by default, which OpenCV can’t decode. Convert first with the built-in sips tool:
The script’s discover_images() automatically prefers <name>_converted.png over a same-named raw .heic/.HEIC file.

Sanity-checking a new embedder model

If you ever swap the embedder, don’t trust it on real photos alone — run it against degenerate inputs first (see Models → the general lesson). A minimal version of that check:
If noise1 vs noise2 comes back near 1.0, the model isn’t meaningfully processing its input — don’t trust its output on real photos either.