auto-save 2026-05-17 19:32 (~4)
This commit is contained in:
70
api/main.py
70
api/main.py
@@ -4274,12 +4274,54 @@ PRODUCT_VIEW_LABELS = {
|
||||
"back_bottom": "背面/底部",
|
||||
}
|
||||
|
||||
PRODUCT_BACKGROUND_VALUES = ["white", "black", "simple", "complex", "unknown"]
|
||||
PRODUCT_USE_TAG_VALUES = [
|
||||
"hero_packshot",
|
||||
"wearing_scale",
|
||||
"inner_contact",
|
||||
"side_thickness",
|
||||
"asymmetry",
|
||||
"button_detail",
|
||||
"back_bottom",
|
||||
"material_texture",
|
||||
]
|
||||
|
||||
|
||||
def default_product_use_tags(view: str) -> list[str]:
|
||||
defaults = {
|
||||
"front": ["hero_packshot", "asymmetry"],
|
||||
"left_45": ["hero_packshot", "asymmetry", "button_detail"],
|
||||
"right_45": ["hero_packshot", "asymmetry", "button_detail"],
|
||||
"side_thickness": ["side_thickness", "wearing_scale"],
|
||||
"inner_contacts": ["inner_contact", "wearing_scale"],
|
||||
"back_bottom": ["back_bottom", "material_texture"],
|
||||
}
|
||||
return defaults.get(view, ["hero_packshot"])
|
||||
|
||||
|
||||
def normalize_product_use_tags(tags: object, view: str) -> list[str]:
|
||||
if isinstance(tags, str):
|
||||
raw_tags = re.split(r"[,,/、\s]+", tags)
|
||||
elif isinstance(tags, list):
|
||||
raw_tags = [str(x) for x in tags]
|
||||
else:
|
||||
raw_tags = []
|
||||
result = []
|
||||
for tag in raw_tags + default_product_use_tags(view):
|
||||
tag = str(tag).strip()
|
||||
if tag in PRODUCT_USE_TAG_VALUES and tag not in result:
|
||||
result.append(tag)
|
||||
return result[:4]
|
||||
|
||||
|
||||
def fallback_product_view(index: int) -> dict:
|
||||
view = PRODUCT_VIEW_VALUES[min(index, len(PRODUCT_VIEW_VALUES) - 1)]
|
||||
return {
|
||||
"view": view,
|
||||
"background": "unknown",
|
||||
"use_tags": default_product_use_tags(view),
|
||||
"note": f"{PRODUCT_VIEW_LABELS.get(view, view)}参考;模型识别不可用时按上传顺序自动标注,请人工只检查备注。",
|
||||
"risk": "模型识别不可用,按上传顺序兜底",
|
||||
"confidence": 0.25,
|
||||
}
|
||||
|
||||
@@ -4300,21 +4342,37 @@ def parse_product_view_response(raw: str, index: int) -> dict:
|
||||
flags=re.I,
|
||||
)
|
||||
confidence_match = re.search(r'["\']?confidence["\']?\s*[::]\s*["\']?([0-9.]+)', text, flags=re.I)
|
||||
background_match = re.search(r'["\']?background["\']?\s*[::]\s*["\']?([a-z0-9_]+)', text, flags=re.I)
|
||||
tags_match = re.search(r'["\']?use_tags["\']?\s*[::]\s*\[([\s\S]*?)\]', text, flags=re.I)
|
||||
risk_match = re.search(
|
||||
r'["\']?risk["\']?\s*[::]\s*["\']?([\s\S]*?)(?:["\']?\s*[,}]\s*$)',
|
||||
text,
|
||||
flags=re.I,
|
||||
)
|
||||
data = {
|
||||
"view": view_match.group(1) if view_match else "",
|
||||
"background": background_match.group(1) if background_match else "unknown",
|
||||
"use_tags": re.findall(r"[a-z_]+", tags_match.group(1)) if tags_match else [],
|
||||
"note": note_match.group(1) if note_match else "",
|
||||
"risk": risk_match.group(1) if risk_match else "",
|
||||
"confidence": confidence_match.group(1) if confidence_match else 0.45,
|
||||
}
|
||||
view = str(data.get("view") or "").strip().strip('"\' ,。')
|
||||
if view not in PRODUCT_VIEW_VALUES:
|
||||
return fallback_product_view(index)
|
||||
background = str(data.get("background") or "unknown").strip().strip('"\' ,。')
|
||||
if background not in PRODUCT_BACKGROUND_VALUES:
|
||||
background = "unknown"
|
||||
use_tags = normalize_product_use_tags(data.get("use_tags"), view)
|
||||
note = str(data.get("note") or "").strip().strip('"\' ,,。')
|
||||
note = re.sub(r"\s+", " ", note)[:220] or f"{PRODUCT_VIEW_LABELS.get(view, view)}参考"
|
||||
risk = str(data.get("risk") or "").strip().strip('"\' ,,。')
|
||||
risk = re.sub(r"\s+", " ", risk)[:120]
|
||||
try:
|
||||
confidence = max(0.0, min(1.0, float(data.get("confidence", 0.5))))
|
||||
except Exception:
|
||||
confidence = 0.5
|
||||
return {"view": view, "note": note, "confidence": confidence}
|
||||
return {"view": view, "background": background, "use_tags": use_tags, "note": note, "risk": risk, "confidence": confidence}
|
||||
|
||||
|
||||
def analyze_product_view(ref_path: Path, index: int) -> dict:
|
||||
@@ -4324,10 +4382,13 @@ def analyze_product_view(ref_path: Path, index: int) -> dict:
|
||||
prompt = (
|
||||
"You are inspecting a product reference image for a SKG neck-and-shoulder wearable massage device. The background may be white, black, or simple studio color. "
|
||||
"Classify the camera/view angle into exactly one enum: front, left_45, right_45, side_thickness, inner_contacts, back_bottom. "
|
||||
"Also write a concise Chinese note for video generation, focused on visible structure, asymmetry, thickness, inner massage contacts, buttons, opening width, and shoulder-neck wearing scale. "
|
||||
"Classify background into exactly one enum: white, black, simple, complex, unknown. Do not request or perform background conversion. "
|
||||
"Add use_tags from this enum only: hero_packshot, wearing_scale, inner_contact, side_thickness, asymmetry, button_detail, back_bottom, material_texture. "
|
||||
"Also write a concise Chinese note for video generation, focused on visible structure, asymmetry, thickness, inner massage contacts, buttons, opening width, shoulder-neck wearing scale, and what this image is best used for in video generation. "
|
||||
"Write risk in Chinese only if this reference may mislead video generation, such as cropped product, hand blocking, low detail, strong reflection, or background confusion; otherwise use empty string. "
|
||||
"If uncertain, choose the closest useful view; do not ask the user. "
|
||||
"Output one-line strict JSON only. Do not use markdown or line breaks. "
|
||||
"{\"view\":\"front|left_45|right_45|side_thickness|inner_contacts|back_bottom\", \"note\":\"中文备注\", \"confidence\":0.0}."
|
||||
"{\"view\":\"front|left_45|right_45|side_thickness|inner_contacts|back_bottom\", \"background\":\"white|black|simple|complex|unknown\", \"use_tags\":[\"hero_packshot\"], \"note\":\"中文备注\", \"risk\":\"\", \"confidence\":0.0}."
|
||||
)
|
||||
try:
|
||||
resp = llm().chat.completions.create(
|
||||
@@ -4364,7 +4425,10 @@ def analyze_product_views(job_id: str, req: AnalyzeProductViewsReq) -> dict:
|
||||
items.append({
|
||||
"index": index,
|
||||
"view": result["view"],
|
||||
"background": result.get("background", "unknown"),
|
||||
"use_tags": result.get("use_tags", default_product_use_tags(result["view"])),
|
||||
"note": result["note"],
|
||||
"risk": result.get("risk", ""),
|
||||
"confidence": result["confidence"],
|
||||
})
|
||||
used = {item["view"] for item in items}
|
||||
|
||||
Reference in New Issue
Block a user