# WL-814x4 — 부위 그룹(M05/Skin/Hair)별로 _DiffuseColor 역이득을 따로 탐색한다. # 전역 이득 1개로는 못 맞추는 이유 = 부위마다 밝기 분포가 달라 그레이딩 회전량이 다르기 때문. import json, sys import numpy as np from PIL import Image RAW='Screenshots_WL/WL814x/4th/raw' REN=sys.argv[1] if len(sys.argv)>1 else 'a_now' def L(n): return np.asarray(Image.open(RAW+'/'+n+'.png').convert('RGB'),dtype=np.uint8) def lum(c): return 0.299*c[0]+0.587*c[1]+0.114*c[2] def hue(c): r,g,b=[float(x) for x in c]; mx,mn=max(r,g,b),min(r,g,b); d=mx-mn if d<1e-6: return 0.0 if mx==r: h=((g-b)/d)%6 elif mx==g: h=(b-r)/d+2 else: h=(r-g)/d+4 return h*60.0 def sat(c): mx=max(c); return (mx-min(c))/mx if mx>1e-6 else 0 def dh(a,b): return (b-a+540)%360-180 idm=L('idmap'); maF=L('mask_Face')[:,:,0]>127; ma=(L('mask_all')[:,:,0]>127)&~maF G=np.array(Image.open('Assets/WL/Look/Character/Textures/WLPalette_FINAL.png')).shape[0]//8 idref=np.array([[9+j*15,240-j*11,40+j*7] for j in range(G*G)],np.float32) fl=idm.reshape(-1,3).astype(np.float32); d2=((fl[:,None,:]-idref[None,:,:])**2).sum(2) kid=np.where((d2.min(1).reshape(idm.shape[:2])<400)&(idm.sum(2)>12), d2.argmin(1).reshape(idm.shape[:2]), -1) tgt={int(k):np.array(v,np.float32) for k,v in json.load(open('AgentScripts/WL814x2_target.json')).items()} PART={'Body_m05':'M05','Arm_m05':'M05','Leg_M05':'M05','Head':'Skin','Hair05':'Hair'} pm={p:(L('mask_'+p)[:,:,0]>127) for p in PART} im=L(REN) cells={} for j in range(G*G): sel=ma&(kid==j); n=int(sel.sum()) if n<800: continue grp=PART[max(((k,int((sel&v).sum())) for k,v in pm.items()),key=lambda t:t[1])[0]] cells.setdefault(grp,[]).append((j,n,tgt[j].astype(np.float64),im[sel].mean(0).astype(np.float64))) best={} print('%-6s %-24s %8s %8s (칸 %d)'%('그룹','최적 _DiffuseColor','dHue','최대',0)) for grp,cs in cells.items(): def ev(g, full=False): e=[];w=[];pen=0.0;pw=0.0 for j,n,o,s in cs: c=np.clip(s*g,0,255) if sat(o)>0.12: e.append(abs(dh(hue(o),hue(c)))); w.append(n) # 채도 보존: 보정으로 채도가 줄면(색이 빠지면) 벌점 pen += n*max(0.0, sat(s)-sat(c))*260.0; pw += n else: # 무채색 목표(흰옷·부츠)는 화면에서도 무채여야 한다 pen += n*max(0.0, sat(c)-0.14)*700.0; pw += n if not e: return 0.0,0.0,0.0 e=np.array(e);w=np.array(w,float) return (e*w).sum()/w.sum(), e.max(), pen/max(pw,1) bb=None for gr in np.arange(0.88,1.145,0.005): for gb in np.arange(0.80,1.145,0.005): gg=(1.0-0.299*gr-0.114*gb)/0.587 if gg<0.88 or gg>1.15: continue g=np.array([gr,gg,gb]); a,m,pn=ev(g) sc=a+0.4*m+pn if bb is None or sc