# Critique helper: sheet crop vs model render, stacked and blended at the same scale (2x the sheet box). import os SHEET_IMG=os.environ.get('SHEET','critique/sheet_clean.png') from PIL import Image, ImageChops, ImageFilter, ImageOps import sys REF = Image.open(SHEET_IMG).convert('RGB') BOX = dict(top=(30,40,970,520), side=(30,530,970,1065), front=(970,30,1410,530), rear=(960,545,1410,1030)) for v,b in BOX.items(): w,h = b[2]-b[0], b[3]-b[1] r = REF.crop(b).resize((w*2,h*2), Image.LANCZOS) m = Image.open(f'previews/compare/lk_{v}.png').convert('RGB').resize((w*2,h*2), Image.LANCZOS) st = Image.new('RGB', (w*2, h*4), 'white'); st.paste(r,(0,0)); st.paste(m,(0,h*2)); st.save(f'critique/stack_{v}.png') Image.blend(r, m, 0.5).save(f'critique/blend_{v}.png') # model edges in red over the sheet e = ImageOps.grayscale(m).filter(ImageFilter.FIND_EDGES).point(lambda p: 255 if p>40 else 0) o = r.copy(); red = Image.new('RGB', r.size, (255,0,0)); o.paste(red, (0,0), e); o.save(f'critique/edge_{v}.png')