Project_WL/AgentScripts/WL814x4_eval.py

56 lines
2.8 KiB
Python
Raw Normal View History

# WL-814x3 평가기 — 안별로 ① 부위 dHue ② 최적 _DiffuseColor 역이득(예측) ③ 게임 크기 고유색
import json, sys
import numpy as np
from PIL import Image
RAW='Screenshots_WL/WL814x/4th/raw'
def L(n): return np.asarray(Image.open(RAW+'/'+n+'.png').convert('RGB'),dtype=np.uint8)
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()}
NAME={8:'머리칼(주)',4:'머리칼(밝)',2:'흰튜닉',1:'가죽갑옷',15:'붉은바지',0:'머리피부',5:'다리피부',14:'부츠흰면',11:'팔소매',10:'벨트',12:'머리칼(하)',3:'부츠갈색',13:'가죽(어두운)',9:'붉은천'}
cells=[]
for j in range(G*G):
sel=ma&(kid==j); n=int(sel.sum())
if n<800: continue
cells.append((j,n,sel,tgt[j]))
m10=L('mask_all10')[:,:,0]>127
def cellmeans(im):
return [(j,n,o,im[sel].mean(0).astype(np.float64)) for j,n,sel,o in cells]
def errs(cm,g):
return [(j,n,o,np.clip(s*g,0,255),dh(hue(o),hue(np.clip(s*g,0,255))),sat(o)) for j,n,o,s in cm]
def wavg(out):
ch=[(n,abs(e)) for j,n,o,s,e,so in out if so>0.12]
w=np.array([c[0] for c in ch],float); e=np.array([c[1] for c in ch])
return (e*w).sum()/w.sum(), e.max()
print('%-18s %7s %7s | %-22s %7s %7s | %6s %6s'%('','dHue','최대','최적 _DiffuseColor','dHue*','최대*','고유색','비율%'))
best={}
for v in sys.argv[1:]:
cm=cellmeans(L(v))
o0=errs(cm,np.ones(3)); a0,m0=wavg(o0)
bb=None
for gr in np.arange(0.80,1.25,0.015):
for gb in np.arange(0.70,1.35,0.015):
gg=(1.0-0.299*gr-0.114*gb)/0.587
if gg<0.7 or gg>1.4: continue
g=np.array([gr,gg,gb]); a,m=wavg(errs(cm,g))
sc=a+0.35*m
if bb is None or sc<bb[0]: bb=(sc,g,a,m)
g=L(v+'_g')[m10]; k=(g[:,0].astype(np.int32)<<16)|(g[:,1].astype(np.int32)<<8)|g[:,2].astype(np.int32)
uc=len(np.unique(k))
print('%-18s %7.1f %7.1f | %-22s %7.1f %7.1f | %6d %6.1f'%(v,a0,m0,str(np.round(bb[1],3)),bb[2],bb[3],uc,100.0*uc/m10.sum()))
best[v]=bb[1]
json.dump({k:[float(x) for x in v] for k,v in best.items()}, open('AgentScripts/WL814x4_gains.json','w'))