| """
|
| Quantified acquisition diversity per source (the measured "why").
|
|
|
| The claim is that the studio source has a uniform, low-entropy background and the
|
| wild source is varied. We measure it: per image we take the border region (a
|
| background proxy) and its mean brightness/colour, and summarise the spread across
|
| each source. The wild source should show far higher background variability and
|
| colour entropy --- the diversity that makes wild-trained models generalize.
|
|
|
| Pure CPU (PIL + numpy).
|
| """
|
| import sys, os, json, glob
|
| from pathlib import Path
|
|
|
| _base = "/mnt/d/SpiceNet" if os.path.exists("/mnt/d/SpiceNet") else "D:/SpiceNet"
|
| sys.path.insert(0, _base)
|
|
|
| import numpy as np
|
| from PIL import Image
|
| import figstyle
|
|
|
| ROOT = Path(_base)
|
| OUT = ROOT / "outputs" / "diversity_index"
|
| CAP = 700
|
|
|
|
|
| def _wsl(p):
|
| if os.name != "nt" and len(p) > 2 and p[1] == ":":
|
| return f"/mnt/{p[0].lower()}/" + p[2:].replace("\\", "/").lstrip("/")
|
| return p
|
|
|
|
|
| def _paths(manifest):
|
| m = json.load(open(manifest))
|
| ps = []
|
| for split in m["samples"]:
|
| ps += [_wsl(p) for p, _ in m["samples"][split]]
|
| ps = [p for p in ps if os.path.exists(p)]
|
| if len(ps) > CAP:
|
| idx = np.random.RandomState(0).choice(len(ps), CAP, replace=False)
|
| ps = [ps[i] for i in idx]
|
| return ps
|
|
|
|
|
| def _stats(path, n=128, f=16):
|
| im = np.asarray(Image.open(path).convert("RGB").resize((n, n)), float)
|
| mask = np.zeros((n, n), bool)
|
| mask[:f] = mask[-f:] = mask[:, :f] = mask[:, -f:] = True
|
| border = im[mask]
|
| bmean = border.mean(0)
|
|
|
| q = (im // 64).astype(int).clip(0, 3)
|
| idx = q[..., 0] * 16 + q[..., 1] * 4 + q[..., 2]
|
| hist = np.bincount(idx.ravel(), minlength=64).astype(float)
|
| p = hist / hist.sum()
|
| ent = -(p[p > 0] * np.log2(p[p > 0])).sum()
|
| return bmean, ent
|
|
|
|
|
| def _source(manifest):
|
| bmeans, ents = [], []
|
| for p in _paths(manifest):
|
| try:
|
| bm, e = _stats(p); bmeans.append(bm); ents.append(e)
|
| except Exception:
|
| pass
|
| bmeans = np.array(bmeans); ents = np.array(ents)
|
| bright = bmeans.mean(1)
|
| return {"bg_brightness": bright, "entropy": ents,
|
| "bg_spread": float(bmeans.std(0).mean()),
|
| "entropy_mean": float(ents.mean()), "n": int(len(ents))}
|
|
|
|
|
| def main():
|
| studio = _source(str(ROOT / "outputs/manifest_overlap_indian.json"))
|
| wild = _source(str(ROOT / "outputs/manifest_overlap_ss.json"))
|
| json.dump({"studio": {k: v for k, v in studio.items() if not isinstance(v, np.ndarray)},
|
| "wild": {k: v for k, v in wild.items() if not isinstance(v, np.ndarray)}},
|
| open(ROOT / "outputs" / "diversity_index.json", "w"), indent=2)
|
|
|
| figstyle.apply()
|
| import matplotlib.pyplot as plt
|
| P = figstyle.PALETTE
|
| fig, (axA, axB) = plt.subplots(1, 2, figsize=(11, 4.4))
|
| bins = np.linspace(0, 255, 40)
|
| axA.hist(studio["bg_brightness"], bins=bins, color=P["studio"], alpha=0.75,
|
| label=f"studio (spread {studio['bg_spread']:.1f})")
|
| axA.hist(wild["bg_brightness"], bins=bins, color=P["wild"], alpha=0.75,
|
| label=f"wild (spread {wild['bg_spread']:.1f})")
|
| axA.set_xlabel("background brightness (border region)"); axA.set_ylabel("images")
|
| axA.set_title("Background variability by source", fontsize=11)
|
| axA.legend(loc="upper left", fontsize=9); axA.grid(axis="y", alpha=0.25)
|
|
|
| axB.hist(studio["entropy"], bins=30, color=P["studio"], alpha=0.75,
|
| label=f"studio (mean {studio['entropy_mean']:.2f})")
|
| axB.hist(wild["entropy"], bins=30, color=P["wild"], alpha=0.75,
|
| label=f"wild (mean {wild['entropy_mean']:.2f})")
|
| axB.set_xlabel("image colour entropy (bits)"); axB.set_ylabel("images")
|
| axB.set_title("Colour entropy by source", fontsize=11)
|
| axB.legend(loc="upper left", fontsize=9); axB.grid(axis="y", alpha=0.25)
|
| fig.tight_layout()
|
| figstyle.save(fig, str(OUT))
|
| print(f"studio: bg-spread {studio['bg_spread']:.1f}, entropy {studio['entropy_mean']:.2f}")
|
| print(f"wild: bg-spread {wild['bg_spread']:.1f}, entropy {wild['entropy_mean']:.2f}")
|
|
|
|
|
| if __name__ == "__main__":
|
| main()
|
|
|