# Critique round 1: the sheet's key shapes (read in sheet pixels) drawn over the sheet crop (left) and over the model render (right). import os SHEET_IMG=os.environ.get('SHEET','critique/sheet_clean.png') from PIL import Image, ImageDraw BOX = dict(side=(30,530,970,1065), front=(970,30,1410,530)) K = 2 T = { 'front': [ ('ellipse', (1185-105, 194, 1185+105, 360), (0,170,255)), # glass dome ('line', [(1080,305),(1073,290),(1071,270),(1074,250),(1082,230),(1066,215),(1050,207),(1082,190),(1108,175),(1137,160), (1160,150),(1213,150),(1235,160),(1264,175),(1289,190),(1321,207),(1305,215),(1289,230),(1297,250),(1300,270), (1298,290),(1290,305)], (255,120,0)), # orange bezel + hood outer edge ('rect', (1040,205,1081,300), (90,0,160)), ('rect', (1290,205,1331,300), (90,0,160)), # dark pods / cavities ('line', [(1105,345),(1150,470),(1159,478),(1166,450),(1172,450),(1186,490),(1199,450),(1205,450),(1210,478),(1222,470),(1265,345)], (200,40,0)), # jaw, fangs, keel tooth ('line', [(1092,330),(997,490),(1061,330)], (0,140,0)), ('line', [(1278,330),(1372,490),(1310,330)], (0,140,0)), # big fins (straight) ], 'side': [ ('line', [(290,674),(286,720),(298,740),(301,760),(300,780),(293,800),(305,815),(325,800),(334,780),(339,760),(338,740),(333,720),(338,668)], (255,120,0)), # collar band ('line', [(200,706),(290,678)], (255,120,0)), ('line', [(200,706),(290,712)], (255,120,0)), # hood wedge over the glass ('line', [(42,792),(60,812),(80,830),(100,845),(120,856),(300,836)], (0,170,255)), # glass lower edge / sill ('line', [(120,856),(157,880),(186,900),(215,920),(243,940),(262,960),(282,980)], (200,40,0)), # jaw front edge ('line', [(296,836),(368,840),(372,856),(372,895),(342,905),(296,900)], (200,40,0)), # jaw's rear C (opening 296-372 x 856-900) ('line', [(338,702),(420,700),(445,745)], (90,0,160)), # cavity under the shell (its rear hook) ('line', [(388,758),(420,722),(440,703),(448,712),(445,735),(425,758),(388,758)], (0,0,0)), # black slanted slot under the shell's hook ('ellipse', (354,748,362,756), (0,0,0)), # small round port ('line', [(280,820),(342,800),(392,780),(431,760),(470,742),(470,745),(492,790),(495,905)], (0,140,0)), ('line', [(300,832),(375,845),(605,1045),(495,905)], (0,140,0)), # cheek panel + fin ('line', [(640,830),(655,790),(700,768),(800,768),(860,790),(860,830),(640,830)], (0,170,255)), # long low side glass bay ]} for v,items in T.items(): b=BOX[v]; w,h=b[2]-b[0],b[3]-b[1] sheet=Image.open(SHEET_IMG).convert('RGB').crop(b).resize((w*K,h*K),Image.LANCZOS) m=Image.open(f'previews/compare/lk_{v}.png').convert('RGBA').resize((w*K,h*K),Image.LANCZOS) bg=Image.new('RGBA',m.size,(255,255,255,255)); bg.alpha_composite(m); m=bg.convert('RGB') out=[] for im in (sheet,m): d=ImageDraw.Draw(im) P=lambda p:((p[0]-b[0])*K,(p[1]-b[1])*K) for kind,geo,col in items: if kind=='ellipse': d.ellipse([*P(geo[:2]),*P(geo[2:])],outline=col,width=4) elif kind=='rect': d.rectangle([*P(geo[:2]),*P(geo[2:])],outline=col,width=4) else: d.line([P(p) for p in geo],fill=col,width=4) out.append(im) c=Image.new('RGB',(w*K*2+20,h*K),'white'); c.paste(out[0],(0,0)); c.paste(out[1],(w*K+20,0)) c.save(f'critique/r1_targets_{v}.png')