feat(vision): 人物图片分析质量提升 v5(assembler字段扩充+migration 098 seed) #2218
File diff suppressed because one or more lines are too long
@@ -420,7 +420,7 @@ def _assemble_v4(idx: int, fj: dict, ocr_texts: list[str]) -> dict[str, Any]:
|
||||
|
||||
# 人物类
|
||||
if vtype == "person" or has_person:
|
||||
# 取第一个人物信息(v4 schema人物信息在顶层)
|
||||
# 取第一个人物信息(v5 schema人物信息在顶层)
|
||||
person_info = fj
|
||||
# 兼容people嵌套
|
||||
ppl = fj.get("people")
|
||||
@@ -429,58 +429,75 @@ def _assemble_v4(idx: int, fj: dict, ocr_texts: list[str]) -> dict[str, Any]:
|
||||
has_person = True
|
||||
|
||||
portrait_prompt = _build_portrait_prompt_from_v4(person_info)
|
||||
name = person_info.get("upper_wear") or "人物穿搭"
|
||||
if "连衣裙" in name:
|
||||
pass
|
||||
outfit_style = person_info.get("outfit_style") or ""
|
||||
upper = person_info.get("upper_wear") or ""
|
||||
lower = person_info.get("lower_wear") or ""
|
||||
dress = person_info.get("dress_wear") or ""
|
||||
outer = person_info.get("outerwear") or ""
|
||||
if dress:
|
||||
name = str(dress)[:25]
|
||||
elif outer and upper:
|
||||
name = f"{outer}+{upper}"[:30]
|
||||
elif upper:
|
||||
name = (str(upper) + (f"+{lower}" if lower else ""))[:30]
|
||||
else:
|
||||
lower = person_info.get("lower_wear") or ""
|
||||
if lower:
|
||||
name = f"{name}+{lower}"
|
||||
name = "人物穿搭"
|
||||
brand = "无法判断"
|
||||
category = "服饰"
|
||||
outfit_parts = []
|
||||
for k in ("upper_wear", "lower_wear", "dress_color", "upper_color", "lower_color", "outfit_style"):
|
||||
category = "人物穿搭"
|
||||
# appearance: 外套+上衣+下装/裙+鞋+包+发型+妆容
|
||||
app_parts = []
|
||||
for k in ("outerwear", "upper_wear", "lower_wear", "dress_wear", "shoes", "bag", "hairstyle", "makeup"):
|
||||
v = person_info.get(k)
|
||||
if v and v not in ("null", None):
|
||||
outfit_parts.append(str(v))
|
||||
appearance = "、".join(outfit_parts) if outfit_parts else "人像穿搭整体造型"
|
||||
# key_features: 穿搭特征+配饰
|
||||
if v and v not in ("null", None, "无明显妆容"):
|
||||
app_parts.append(str(v))
|
||||
appearance = ";".join(app_parts) if app_parts else "人像穿搭整体造型"
|
||||
# key_features: 服装+配饰+拍摄信息
|
||||
kf = []
|
||||
for k in (
|
||||
"outfit_style",
|
||||
"upper_wear",
|
||||
"lower_wear",
|
||||
"upper_color",
|
||||
"lower_color",
|
||||
"dress_wear",
|
||||
"outerwear",
|
||||
"shoes",
|
||||
"bag",
|
||||
"hairstyle",
|
||||
"expression",
|
||||
"pose",
|
||||
"outfit_style",
|
||||
):
|
||||
v = person_info.get(k)
|
||||
if v and v not in ("null", None, "无法判断"):
|
||||
kf.append(str(v))
|
||||
acc = person_info.get("accessories") or []
|
||||
if isinstance(acc, list):
|
||||
kf.extend(str(a) for a in acc if a)
|
||||
for a in acc:
|
||||
if a and str(a) not in kf:
|
||||
kf.append(str(a))
|
||||
elif isinstance(acc, str) and acc:
|
||||
kf.append(acc)
|
||||
for k in ("shot_type", "camera_angle", "lighting", "atmosphere"):
|
||||
v = person_info.get(k)
|
||||
if v and v not in ("null", None):
|
||||
kf.append(str(v))
|
||||
if text_on_package:
|
||||
kf.append(f"画面文字: {'/'.join(text_on_package[:3])}")
|
||||
kf = kf[:6] or ["无法判断"]
|
||||
summary = (person_info.get("outfit_style") or "") + (person_info.get("upper_wear") or "穿搭")
|
||||
if not summary or summary == "穿搭":
|
||||
kf.append(f"文字:{'/'.join(text_on_package[:3])}")
|
||||
kf = kf[:8] or ["无法判断"]
|
||||
summary = (outfit_style + " " if outfit_style and outfit_style not in name else "") + name[:25]
|
||||
if not summary.strip():
|
||||
summary = "人物穿搭"
|
||||
return {
|
||||
"name": name[:30],
|
||||
"brand": brand,
|
||||
"category": category,
|
||||
"appearance": appearance,
|
||||
"appearance": appearance[:400],
|
||||
"packaging": "人物形象无包装",
|
||||
"text_on_package": text_on_package,
|
||||
"key_features": kf,
|
||||
"scene": scene,
|
||||
"mood": mood,
|
||||
"portrait_prompt": portrait_prompt,
|
||||
"summary": summary[:40],
|
||||
"_source": "v2_fast_json_v4",
|
||||
"portrait_prompt": portrait_prompt[:300],
|
||||
"summary": summary[:50],
|
||||
"_source": "v2_fast_json_v5",
|
||||
}
|
||||
|
||||
# 商品类
|
||||
|
||||
@@ -137,18 +137,18 @@ V4_PERSON: dict[str, Any] = {
|
||||
def test_assemble_v4_person() -> None:
|
||||
r = assembler.assemble_result(0, V4_PERSON, [])
|
||||
assert REQUIRED_KEYS <= set(r.keys())
|
||||
assert r["category"] == "服饰"
|
||||
assert r["category"] == "人物穿搭"
|
||||
assert r["_source"] == "v2_fast_json_v5"
|
||||
assert "T恤" in r["name"]
|
||||
assert "阔腿裤" in r["name"]
|
||||
assert "年轻女性" in r["portrait_prompt"]
|
||||
assert "项链" in r["portrait_prompt"]
|
||||
assert isinstance(r["key_features"], list) and len(r["key_features"]) <= 6
|
||||
assert isinstance(r["key_features"], list) and len(r["key_features"]) <= 8
|
||||
|
||||
|
||||
def test_assemble_v4_person_people_nested() -> None:
|
||||
fj = {"type": "person", "people": {**V4_PERSON, "has_person": True}}
|
||||
r = assembler.assemble_result(0, fj, [])
|
||||
assert r["category"] == "服饰"
|
||||
assert r["category"] == "人物穿搭"
|
||||
assert "年轻女性" in r["portrait_prompt"]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user