"""I1. Paint map: share of page pixels in each pigment class (green, blue, red/brown, yellow) for every folio image, from Yale's photographs (2,000 px). Vellum vs background is found by brightness; pigment classes by HSV thresholds tuned on known pages. Joined to the codex map so paint use can be compared across quires, scribes and languages. Outputs: out/paint_map.csv """ import os, sys _here = os.path.dirname(os.path.abspath(__file__)) # data/analysis, or a subfolder of it sys.path.insert(0, _here if os.path.exists(os.path.join(_here, "paths.py")) else os.path.dirname(_here)) from paths import * # noqa: repository locations import os, re, csv, json, sys import numpy as np from PIL import Image IMG = IMG rows = [] codex = {r["page"]: r for r in csv.DictReader(open(os.path.join(TABLES, "codex_map.csv")))} files = sorted(os.listdir(IMG)) def classify(path): im = Image.open(path).convert("RGB"); im.thumbnail((700, 700)) a = np.asarray(im).astype(float) / 255 hsv = np.asarray(im.convert("HSV")).astype(float) / 255 h, s, v = hsv[..., 0], hsv[..., 1], hsv[..., 2] page = v > 0.35 # vellum (black background excluded) n = page.sum() green = page & (h > 0.20) & (h < 0.47) & (s > 0.22) blue = page & (h > 0.50) & (h < 0.72) & (s > 0.20) red = page & ((h < 0.06) | (h > 0.92)) & (s > 0.35) & (v > 0.25) yellow = page & (h > 0.09) & (h < 0.19) & (s > 0.40) & (v > 0.5) brown_ink = page & (v < 0.45) & (s < 0.6) # ink/dark strokes (text + outlines) return dict(page_px=int(n), green=green.sum() / n, blue=blue.sum() / n, red=red.sum() / n, yellow=yellow.sum() / n, ink=brown_ink.sum() / n) for f in files: m = re.match(r"\d{3}_(\d+[rv])(?:_part)?\.jpg", f) if not m: continue folio = m.group(1) # map to ZL page names: plain folio pages; fold-out panels get the whole image r = classify(os.path.join(IMG, f)) cm = codex.get("f" + folio) rows.append(dict(file=f, folio=folio, quire=cm["quire"] if cm else "", section=cm["section"] if cm else "", lang=cm["lang"] if cm else "", hand=cm["hand"] if cm else "", **r)) print(f, {k: round(v, 3) for k, v in r.items() if k != "page_px"}, flush=True) with open(os.path.join(TABLES, "paint_map.csv"), "w", newline="") as fh: w = csv.DictWriter(fh, fieldnames=rows[0].keys()); w.writeheader(); w.writerows(rows) print(len(rows))