# Critique helper: crop the same SHEET-pixel region from the sheet and from the model render, side by side, with a ruler. # usage: pair.py view x0 y0 x1 y1 scale out.png import sys import os SHEET_IMG=os.environ.get('SHEET','critique/sheet_clean.png') from PIL import Image, ImageDraw BOX = dict(top=(30,40,970,520), side=(30,530,970,1065), front=(970,30,1410,530), rear=(960,545,1410,1030)) v=sys.argv[1]; x0,y0,x1,y1=map(int,sys.argv[2:6]); s=float(sys.argv[6]); out=sys.argv[7] b=BOX[v]; w,h=b[2]-b[0],b[3]-b[1] sheet=Image.open(SHEET_IMG).convert('RGB') m=Image.open(f'previews/compare/lk_{v}.png').convert('RGBA') mw,mh=m.size; fx,fy=mw/w,mh/h bg=Image.new('RGBA',m.size,(255,255,255,255)); bg.alpha_composite(m); m=bg.convert('RGB') a=sheet.crop((x0,y0,x1,y1)).resize((int((x1-x0)*s),int((y1-y0)*s)),Image.LANCZOS) c=m.crop((int((x0-b[0])*fx),int((y0-b[1])*fy),int((x1-b[0])*fx),int((y1-b[1])*fy))).resize(a.size,Image.LANCZOS) W,H=a.size; im=Image.new('RGB',(W*2+40,H+30),'white'); im.paste(a,(30,30)); im.paste(c,(W+40,30)) d=ImageDraw.Draw(im) step=10 if (x1-x0)<200 else 25 for X in range((x0//step+1)*step,x1,step): for off in (30,W+40): px=off+(X-x0)*s; d.line([(px,30),(px,H+30)],fill=(255,0,255) if X%50==0 else (120,200,255),width=1) if X%50==0: d.text((px+2,2),str(X),fill='black') for Y in range((y0//step+1)*step,y1,step): py=30+(Y-y0)*s; d.line([(30,py),(W*2+40,py)],fill=(255,0,255) if Y%50==0 else (120,200,255),width=1) if Y%50==0: d.text((2,py),str(Y),fill='black') im.save(out)