feat(接口4): 用户特征-火山方舟豆包视觉模型(替换Mock)
接口4 改用远程视觉大模型(算法来源 /home/xsl/fuyan),一次返回几十项面部特征。 - face_features.py: 火山方舟 Ark 客户端(单例)+doubao-seed-1-6-vision prompt(移植fuyan) +base64 data URI喂图(实测doubao接受)+解析JSON+映射6英文优先字段(face_shape等) 并保留doubao全部中文字段;has_face 据"图片是否有人脸"判定 - app.py: /face/features 真实实现,三选一图(image_url直传doubao,file/base64转dataURI), features 为 JSON 字符串;无人脸→1001;重活线程池 - 配置: API Key 走 worker_config.json.ark_api_key / 环境变量 ARK_API_KEY(不入git); worker_config.example 加占位; requirements 加 volcengine-python-sdk[ark] - 文档: 接口文档/OpenAPI 更新为豆包实现+几十项字段+1001 - 测试: mock doubao 的成功/无人脸/多参,47全绿 ⚠️ 唯一调外网云模型的接口,worker 需可达 ark.cn-beijing.volces.com(已实测可达)。 实测 frontal: 42字段, 鹅蛋脸/平眉/18-25岁/静态型/女/少年型。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -630,20 +630,23 @@ async def hair_grow_b(
|
||||
|
||||
---
|
||||
|
||||
由**火山方舟 豆包视觉模型**分析,返回一大批面部特征(脸型/眉形/眼型/肤色/三庭五眼/四季色彩季型/
|
||||
量感/轮廓/基因风格/性别…几十项),**英文优先字段 + doubao 中文字段并存**。
|
||||
|
||||
**返回格式**:`data.features` 为一个 **JSON 字符串**(不是对象),需要在客户端 `JSON.parse()` 后使用。
|
||||
|
||||
当前优先返回字段:
|
||||
英文优先字段(其余中文字段同时返回):
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| face_shape | string | 脸形,如"鹅蛋脸" |
|
||||
| eyebrow_shape | string | 眉形,如"柳叶眉" |
|
||||
| facial_age | int | 面部年龄 |
|
||||
| dynamic_static_type | string | 动静类型,如"静态" |
|
||||
| gender | string | 性别,如"女" |
|
||||
| gene_style | object | 面部特征对应的基因风格 |
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| face_shape | 脸形(如"鹅蛋脸") |
|
||||
| eyebrow_shape | 眉形(如"平眉") |
|
||||
| facial_age | 面部年龄(区间,如"18-25岁") |
|
||||
| dynamic_static_type | 动静类型("静态型"/"动态型") |
|
||||
| gender | 性别("男"/"女") |
|
||||
| gene_style | 基因风格(如"自然型") |
|
||||
|
||||
> 字段后续可随时增删,不固定,客户端按需取用即可。
|
||||
> 字段不固定、可随时增删,客户端按需取用。无人脸返回 `1001`。
|
||||
""",
|
||||
responses={
|
||||
200: {
|
||||
@@ -655,7 +658,7 @@ async def hair_grow_b(
|
||||
"message": "success",
|
||||
"request_id": "mock-request-id",
|
||||
"data": {
|
||||
"features": '{"face_shape": "鹅蛋脸", "eyebrow_shape": "柳叶眉", "facial_age": 26, "dynamic_static_type": "静态", "gender": "女", "gene_style": {"label": "面部特征标签", "style": "基因风格示例"}}',
|
||||
"features": '{"图片是否有人脸":"有人","脸型":"鹅蛋脸","眉形":"平眉","面部年龄":"18-25岁","四季色彩季型":"冷夏型","基因风格":"少年型","性别":"女","face_shape":"鹅蛋脸","eyebrow_shape":"平眉","facial_age":"18-25岁","dynamic_static_type":"静态型","gender":"女","gene_style":"少年型"}',
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -676,18 +679,32 @@ async def face_features(
|
||||
image_url: Optional[str] = Form(default=None, description="图片 URL"),
|
||||
image_base64: Optional[str] = Form(default=None, description="图片 base64(需带 data:image/...;base64, 前缀)"),
|
||||
):
|
||||
features = json.dumps(
|
||||
{
|
||||
"face_shape": "鹅蛋脸",
|
||||
"eyebrow_shape": "柳叶眉",
|
||||
"facial_age": 26,
|
||||
"dynamic_static_type": "静态",
|
||||
"gender": "女",
|
||||
"gene_style": {"label": "面部特征标签", "style": "基因风格示例"},
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
return ok({"features": features})
|
||||
# 三选一。image_url 直接交给豆包拉取;file/base64 解成字节转 data URI。
|
||||
provided = [x for x in (image_file, image_url, image_base64) if x]
|
||||
if len(provided) != 1:
|
||||
return err(1007, "图片参数错误:必须且只能传 image_file / image_url / image_base64 其中一个")
|
||||
|
||||
img_bytes = None
|
||||
if not image_url:
|
||||
raw, e = await resolve_image_bytes(image_file, None, image_base64)
|
||||
if e is not None:
|
||||
return e
|
||||
if len(raw) > MAX_FILE_BYTES:
|
||||
return err(1006, "文件超出 1 MB 限制")
|
||||
img_bytes = raw
|
||||
|
||||
try:
|
||||
from fastapi.concurrency import run_in_threadpool
|
||||
from face_features import analyze_features, has_face
|
||||
|
||||
feats = await run_in_threadpool(analyze_features, img_bytes, image_url)
|
||||
if not has_face(feats):
|
||||
return err(1001, "无法识别人像")
|
||||
# 契约:data.features 为 JSON 字符串
|
||||
return ok({"features": json.dumps(feats, ensure_ascii=False)})
|
||||
except Exception as ex: # noqa: BLE001
|
||||
logger.exception("接口4 处理异常")
|
||||
return err(1007, f"处理失败:{ex}")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user