"""Sheet views beside the model rendered in the same framing, and outline overlays with IoU against the sheet masks. python build/ae_compare.py [render-name-pattern] (renders from ae_render.py 'views' or 'studio')""" import os, sys, json import numpy as np from PIL import Image, ImageDraw ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) CROPS = {'side': (175, 85, 712, 400), 'front': (795, 85, 1135, 400), 'top': (150, 455, 680, 773)} pfx = sys.argv[1] if len(sys.argv) > 1 else 'v01' pat = sys.argv[2] if len(sys.argv) > 2 else '{pfx}_wb_{v}.png' sheet = Image.open(os.path.join(ROOT, 'reference/user_blueprint.png')).convert('RGB') res = {} pairs = [] for v, (x0, y0, x1, y1) in CROPS.items(): p = os.path.join(ROOT, 'previews', 'compare', pat.format(pfx=pfx, v=v)) if not os.path.exists(p): p = os.path.join(ROOT, 'previews', pat.format(pfx=pfx, v=v)) r = Image.open(p).convert('RGBA') W, H = (x1 - x0) * 2, (y1 - y0) * 2 if r.size != (W, H): r = r.resize((W, H), Image.LANCZOS) crop = sheet.crop((x0, y0, x1, y1)).resize((W, H), Image.LANCZOS) bg = Image.new('RGBA', (W, H), (235, 236, 238, 255)); bg.alpha_composite(r) pair = Image.new('RGB', (W * 2 + 10, H), (255, 255, 255)); pair.paste(crop, (0, 0)); pair.paste(bg.convert('RGB'), (W + 10, 0)) pairs.append(pair) # overlay: the model's silhouette outline (red) and the sheet mask's (yellow) on the sheet a = np.asarray(r)[..., 3] > 20 mk = np.asarray(Image.open(os.path.join(ROOT, f'reference/mask_{v}.png')).crop((x0, y0, x1, y1)).resize((W, H))) > 127 iou = (a & mk).sum() / max((a | mk).sum(), 1) res[v] = round(float(iou), 4) def edge(m): return m & ~(np.roll(m, 1, 0) & np.roll(m, -1, 0) & np.roll(m, 1, 1) & np.roll(m, -1, 1)) o = np.asarray(crop).copy() o[edge(mk)] = (255, 220, 0); o[edge(a)] = (255, 30, 30) oi = Image.fromarray(o); ImageDraw.Draw(oi).text((6, 6), f'{v} IoU {iou:.3f} red model yellow sheet', fill=(255, 255, 255)) oi.save(os.path.join(ROOT, 'previews', 'compare', f'{pfx}_overlay_{v}.png')) Wt = max(p.size[0] for p in pairs); Ht = sum(p.size[1] for p in pairs) + 10 * len(pairs) sheet_out = Image.new('RGB', (Wt, Ht), (255, 255, 255)); y = 0 for p in pairs: sheet_out.paste(p, (0, y)); y += p.size[1] + 10 sheet_out.save(os.path.join(ROOT, 'previews', 'compare', f'{pfx}_lookalike.png')) print(json.dumps(res))