104 lines
4.9 KiB
Python
104 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
||
"""CHAR-003 V2 R6 QC · Seedream · R3-02风格 + 17-18岁"""
|
||
import sys, os, json, base64, subprocess
|
||
from pathlib import Path
|
||
|
||
# 读 .env
|
||
ROOT = Path('D:/WorkBuddy/guanghulab/video-ai-system')
|
||
ENV_FILE = ROOT / ".env"
|
||
env = {}
|
||
if ENV_FILE.exists():
|
||
for line in open(ENV_FILE):
|
||
line = line.strip()
|
||
if line and not line.startswith("#") and "=" in line:
|
||
k, v = line.split("=", 1)
|
||
env[k.strip()] = v.strip()
|
||
|
||
AK = env.get("ALIYUN_QWEN_VL_KEY", "")
|
||
EP = env.get("ALIYUN_QWEN_VL_ENDPOINT", "https://ws-umd6xwlovzmshuat.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation")
|
||
FE = "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
|
||
|
||
DIR = ROOT / "assets/candidates/D158-VA-05-001-V2/CHAR-003-SuBai/R6"
|
||
CS = [DIR / f"CHAR-003-V2-R6-candidate-{i:02d}-1080x1920.png" for i in range(1, 5)]
|
||
|
||
PROMPT = """检查CHAR-003苏白立绘。剧本设定:18岁男性,白色长衫,青色腰带,黑色长发半束半披,双手叉腰,自信开朗,气质俊秀略带痞气,穷但不自卑。
|
||
|
||
逐项判定:
|
||
1. 是否为男性?(male: bool)
|
||
2. 是否白色长衫?(white_robe: bool)
|
||
3. 是否有青色/深色腰带?(cyan_sash: bool)
|
||
4. 是否为黑色长发半束半披?(hair_half_tied: bool)
|
||
5. 是否双手叉腰?(hands_on_hips: bool)
|
||
6. 服装是否完整无破损?(intact: bool)
|
||
7. 是否有乞丐感/寒酸感?(beggar: bool)
|
||
8. 是否十七八岁年轻少年?(young: bool)
|
||
9. 是否俊秀自信?(handsome_confident: bool)
|
||
10. 是否与诸葛风长相相似?(like_zhuge: bool)
|
||
11. 五官是否清晰无崩坏?(face_ok: bool)
|
||
12. 全身是否完整?(full_body: bool)
|
||
13. 袖子是否完整(非无袖/背心)?(sleeves_ok: bool)
|
||
|
||
评分规则:
|
||
- 若 male/white_robe/cyan_sash/hair_half_tied/hands_on_hips/intact/young/handsome_confident/face_ok/full_body/sleeves_ok 任一不满足 → pass=false
|
||
- 若 beggar=true 或 like_zhuge=true → pass=false
|
||
|
||
输出JSON: {"candidate": N, "pass": bool, "score": 0-100, "male": bool, "white_robe": bool, "cyan_sash": bool, "hair_half_tied": bool, "hands_on_hips": bool, "intact": bool, "beggar": bool, "young": bool, "handsome_confident": bool, "like_zhuge": bool, "face_ok": bool, "full_body": bool, "sleeves_ok": bool, "summary": "一句话"}"""
|
||
|
||
def encode(p):
|
||
with open(p, "rb") as f:
|
||
b64 = base64.b64encode(f.read()).decode()
|
||
return f"data:image/png;base64,{b64}"
|
||
|
||
def q(img):
|
||
b = json.dumps({"model": "qwen-vl-max", "input": {"messages": [{"role": "user", "content": [{"image": img}, {"text": PROMPT}]}]}})
|
||
for ep in [EP, FE]:
|
||
try:
|
||
r = subprocess.run(["curl", "-s", "-m", "90", "--noproxy", "*", "-X", "POST", ep,
|
||
"-H", f"Authorization: Bearer {AK}", "-H", "Content-Type: application/json", "--data-binary", "@-"],
|
||
input=b, capture_output=True, text=True, timeout=95)
|
||
if not r.stdout.strip():
|
||
continue
|
||
d = json.loads(r.stdout)
|
||
if "output" in d:
|
||
c = d["output"]["choices"][0]["message"]["content"][0]["text"]
|
||
if "```" in c:
|
||
c = c.split("```")[1]
|
||
c = c[4:] if c.startswith("json") else c
|
||
c = c.split("```")[0]
|
||
return json.loads(c.strip())
|
||
except Exception as e:
|
||
continue
|
||
return None
|
||
|
||
rs = []
|
||
for i, p in enumerate(CS):
|
||
print(f"[{i+1}/4]", end=" ", flush=True)
|
||
qc = q(encode(p))
|
||
if qc:
|
||
print(f"s={qc.get('score', '?')} pass={qc.get('pass', '?')}")
|
||
rs.append(qc)
|
||
else:
|
||
print("✗")
|
||
rs.append({"candidate": i+1, "pass": False, "error": "api"})
|
||
|
||
ok = sum(1 for r in rs if r.get("pass"))
|
||
print(f"\n通过: {ok}/4")
|
||
for r in rs:
|
||
if not r.get("pass") and "error" not in r:
|
||
iss = []
|
||
for k, v in r.items():
|
||
if isinstance(v, bool) and v:
|
||
if k in ["male", "white_robe", "cyan_sash", "hair_half_tied", "hands_on_hips", "intact", "young", "handsome_confident", "face_ok", "full_body", "sleeves_ok"]:
|
||
pass
|
||
elif k == "beggar": iss.append("乞丐感")
|
||
elif k == "like_zhuge": iss.append("像诸葛风")
|
||
else: iss.append(k)
|
||
elif isinstance(v, bool) and not v and k in ["male", "white_robe", "cyan_sash", "hair_half_tied", "hands_on_hips", "intact", "young", "handsome_confident", "face_ok", "full_body", "sleeves_ok"]:
|
||
iss.append(f"缺{k}")
|
||
print(f" 候{r.get('candidate')} ✗: {','.join(iss) if iss else '其他'} s={r.get('score')}")
|
||
|
||
rep = {"spec": "VA-05-001-V2-R6", "method": "qwen-vl-auto", "results": rs, "summary": {"passed": ok, "total": 4}}
|
||
with open(DIR / "QC-R6-BATCH.json", "w", encoding="utf-8") as f:
|
||
json.dump(rep, f, ensure_ascii=False, indent=2)
|
||
print(f"\n报告: QC-R6-BATCH.json")
|