guanghulab/video-ai-system/tools/qc_char003_r6.py
bingshuo 580902a3b6
Some checks failed
自动更新代码和重启 / update-and-restart (push) Has been cancelled
CI检查 + 自动部署 / check (push) Has been cancelled
CI检查 + 自动部署 / deploy (push) Has been cancelled
ICE-GL-ZY001 · CHAR-003苏白V2 R6 Seedream 4.0 + Qwen-VL自动质检 · D161
2026-07-02 15:53:07 +08:00

104 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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")