SpiceNet / code /analyze_diversity_index.py
Noushad999's picture
Upload folder using huggingface_hub
1ea7ba6 verified
Raw
History Blame Contribute Delete
4.53 kB
"""
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 frame
border = im[mask] # (P, 3)
bmean = border.mean(0) # mean border colour
# colour entropy of the whole image (coarse 4x4x4 RGB histogram)
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) # border brightness per image
return {"bg_brightness": bright, "entropy": ents,
"bg_spread": float(bmeans.std(0).mean()), # cross-image bg colour spread
"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()