guanghulab/video-ai-system/tools/qc_char004_r5.py

65 lines
3.4 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""CHAR-004 R5 QC · 剧本锚定版 · 素色白衣"""
import sys,os,json,base64,subprocess
sys.path.insert(0,os.path.dirname(__file__))
from secrets_loader import secret,endpoint
AK=secret("SC-004");EP=endpoint("EPT-002");FE="https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
DIR=os.path.expanduser("~/guanghulab/video-ai-system/assets/candidates/D157-VA-05-001-R5/CHAR-004-ZhugeFeng")
CS=[f"{DIR}/CHAR-004-R5-candidate-{i:02d}-1080x1920.jpg" for i in range(1,5)]
P="""检查CHAR-004诸葛风立绘。剧本设定18岁淳朴少年素色粗麻布衣干净整洁。
逐项
1. 衣服是否为素色/白色系(white_clothes:bool)
2. 衣服有无破损/破洞(damaged:bool)
3. 下摆有无毛边(frayed:bool)
4. 裤子膝盖有无破洞(hole_knee:bool)
5. 鞋面有无脏污(dirty_shoes:bool)
6. 服装有无污渍(stains:bool)
7. 整体有无乞丐感/寒酸(beggar:bool)
8. 气质是否淳朴端正(honest:bool)
9. 面部和苏白像不像(like_sb:bool)
10. 五官清晰吗(face_ok:bool)
11. 全身完整吗(full_body:bool)
评分damaged/frayed/hole_knee/dirty_shoes/stains/beggar任一为true pass=false
输出JSON:{"candidate":N,"pass":bool,"score":0-100,"white_clothes":bool,"damaged":bool,"frayed":bool,"hole_knee":bool,"dirty_shoes":bool,"stains":bool,"beggar":bool,"honest":bool,"like_sb":bool,"face_ok":bool,"full_body":bool,"summary":"一句话"}"""
def e(p):
with open(p,"rb") as f: b64=base64.b64encode(f.read()).decode()
return f"data:image/{'jpeg' if p.endswith('jpg') else 'png'};base64,{b64}"
def q(img):
b=json.dumps({"model":"qwen-vl-max","input":{"messages":[{"role":"user","content":[{"image":img},{"text":P}]}]}})
for ep in[EP,FE]:
try:
r=subprocess.run(["curl","-s","-m","60","--noproxy","*","-X","POST",ep,"-H",f"Authorization: Bearer {AK}","-H","Content-Type: application/json","--data-binary","@-"],input=b,capture_output=True,text=True,timeout=65)
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: continue
return None
rs=[]
for i,p in enumerate(CS):
print(f"[{i+1}/4]",end=" ",flush=True)
qc=q(e(p))
if qc:
print(f"s={qc.get('score','?')} pass={qc.get('pass','?')} 白色={qc.get('white_clothes','?')} 破={qc.get('damaged','?')}")
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"):
iss=[];d=r
if d.get("damaged"):iss.append("破损")
if d.get("frayed"):iss.append("毛边")
if d.get("hole_knee"):iss.append("膝盖破洞")
if d.get("dirty_shoes"):iss.append("脏鞋")
if d.get("beggar"):iss.append("乞丐感")
print(f"{r.get('candidate')} ✗: {','.join(iss) if iss else '其他'} s={r.get('score')}")
rep={"spec":"VA-05-001-R5","results":rs,"summary":{"passed":ok,"total":4}}
with open(os.path.join(DIR,"QC-R5-BATCH.json"),"w") as f:json.dump(rep,f,ensure_ascii=False,indent=2)
print(f"\n报告:QC-R5-BATCH.json")