Project_WL/AgentScripts/WL814x_report.py

108 lines
4.8 KiB
Python
Raw Normal View History

# WL-814x 보고용 캡처 묶음 + 합격선 표 이미지 + 외곽선 두께 실측
import os
import numpy as np
from PIL import Image, ImageDraw
RAW = 'Screenshots_WL/WL814x/raw'
OUT = 'Screenshots_WL/WL814x'
def L(n):
return np.asarray(Image.open(RAW + '/' + n + '.png').convert('RGB'), dtype=np.uint8)
ma = L('mask_all')[:, :, 0] > 127
ys, xs = np.where(ma)
pad = 6
X0, X1 = xs.min() - pad, xs.max() + pad + 1
Y0, Y1 = ys.min() - pad, ys.max() + pad + 1
def crop(n, z):
im = Image.open(RAW + '/' + n + '.png').convert('RGB').crop((X0, Y0, X1, Y1))
return im.resize((im.width * z, im.height * z), Image.NEAREST) if z > 1 else im
def grid(out, zoom, names, labels=None):
cells = [(labels[i] if labels else names[i], crop(n, zoom), crop(n, 1)) for i, n in enumerate(names)
if os.path.exists(RAW + '/' + n + '.png')]
gap, lab = 10, 20
W = sum(c[1].width for c in cells) + gap * (len(cells) - 1)
H = cells[0][1].height + cells[0][2].height + gap + lab
img = Image.new('RGB', (W, H), (24, 24, 28))
d = ImageDraw.Draw(img)
x = 0
for t, big, small in cells:
img.paste(big, (x, lab))
img.paste(small, (x + (big.width - small.width) // 2, lab + big.height + gap))
d.text((x + 2, 4), t, fill=(235, 235, 235))
x += big.width + gap
img.save(OUT + '/' + out)
print('saved', out, img.size)
# ── 외곽선 두께 실측: 실루엣 바깥 1px 띠가 거의 검정인가
def outline_px(name):
im = L(name)
inner = np.zeros_like(ma)
inner[1:-1, 1:-1] = ma[1:-1, 1:-1] & ma[:-2, 1:-1] & ma[2:, 1:-1] & ma[1:-1, :-2] & ma[1:-1, 2:]
band1 = ma & ~inner
inner2 = np.zeros_like(ma)
inner2[2:-2, 2:-2] = inner[2:-2, 2:-2] & inner[1:-3, 2:-2] & inner[3:-1, 2:-2] & inner[2:-2, 1:-3] & inner[2:-2, 3:-1]
band2 = inner & ~inner2
def darkfrac(b):
px = im[b]
lum = 0.299 * px[:, 0] + 0.587 * px[:, 1] + 0.114 * px[:, 2]
return 100.0 * (lum < 40).sum() / max(len(px), 1), int(b.sum())
f1, n1 = darkfrac(band1)
f2, n2 = darkfrac(band2)
return f1, n1, f2, n2
if __name__ == '__main__':
grid('iter1.png', 5, ['i1_a_base_now', 'i1_c20p16', 'i1_c40p16', 'i1_c80p16'],
['지금(89.3%/2676)', '덩어리20 팔레트16', '덩어리40 팔레트16', '덩어리80 팔레트16'])
grid('iter2.png', 5, ['i1_a_base_now', 'i2_fV1', 'i2_fP32', 'i2_shades2'],
['지금', '얼굴 814v V1(2048)', '얼굴 P32(1텍셀=1px)', '+셰이드2단'])
grid('iter3.png', 5, ['i1_a_base_now', 'i3_c20p10_s2', 'i3_c40p16_s2', 'i3_c40p16_s3', 'i3_c80p16_s2'],
['지금', 'c20p10 s2', 'c40p16 s2', 'c40p16 s3', 'c80p16 s2'])
grid('iter4.png', 5, ['i1_a_base_now', 'i4_linNos_s3', 'i5_g0none_s3', 'i5_g1soft_s3', 'i5_g2hard_s3'],
['지금', '선형평균', 'sRGB평균 보정없음', '보정 g1soft(채택)', '보정 g2hard'])
grid('z_final_compare.png', 4, ['z_off_now', 'q_runtime'], ['지금 (enabled_=0)', '최종 팔레트 UV (enabled_=1)'])
for n in ['z_off_now', 'q_runtime']:
print(n, '외곽선 1px띠 어두운비율 %.1f%% (%d px) · 2px째 띠 %.1f%% (%d px)' % outline_px(n))
# ── 합격선 표 이미지
rows = [
('항목', '지금', '최종', '합격선', '판정'),
('서로 다른 색 비율', '89.3 %', '1.7 %', '≤ 25 %', 'PASS'),
('캐릭터 영역 고유색 수', '2,676', '52', '≤ 60', 'PASS'),
('부위(덩어리)당 색 단계', '41', '평균 2.79 (14칸 중 13칸 2~3)', '≤ 4', 'PASS*'),
('눈이 어두운 덩어리로', '10 px', '36 px (눈 1개 7×5)', '36 px 유지 이상', 'PASS'),
('색상(Hue) 오차', '-', '몸통 2.4° 피부 3.7° 머리칼 3.5°', '평균 ≤ 8°', 'PASS'),
('실루엣 외곽선', '1 px', '1 px (814t 설정 무변경)', '유지', 'PASS'),
]
cw = [230, 90, 300, 130, 80]
rh = 34
W = sum(cw) + 40
H = rh * len(rows) + 70
img = Image.new('RGB', (W, H), (22, 22, 26))
d = ImageDraw.Draw(img)
d.text((20, 14), 'WL-814x 팔레트 아틀라스 UV — 합격선 6항목 (WL_ArenaProto · 직교10 · 1080x1920 · 캐릭터 2996px)', fill=(255, 235, 160))
for r, row in enumerate(rows):
y = 48 + r * rh
bg = (40, 40, 48) if r == 0 else ((30, 30, 36) if r % 2 else (26, 26, 31))
d.rectangle([16, y, W - 16, y + rh - 2], fill=bg)
x = 20
for c, cell in enumerate(row):
col = (235, 235, 235)
if r > 0 and c == 4:
col = (130, 230, 150)
if r > 0 and c == 2:
col = (150, 210, 255)
d.text((x + 6, y + 9), str(cell), fill=col)
x += cw[c]
d.text((20, 48 + len(rows) * rh + 6), '* 단계 7 인 칸 1개 = 얼굴 데칼이 얹힌 머리 피부 칸(데칼은 별도 부위로 잼)', fill=(200, 200, 200))
img.save(OUT + '/z_metrics.png')
print('saved z_metrics.png', img.size)