接口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>
392 lines
15 KiB
Markdown
392 lines
15 KiB
Markdown
# 旷视五个接口 — 接口文档(输入 / 输出定义)
|
||
|
||
> 本文档依据《旷视具体需求.docx》整理,描述各接口的**输入**与**输出**。
|
||
> 文中标记为 **【待确认】** 的内容为需求文档中尚未明确、需与对方对齐的点。
|
||
|
||
> **当前为第一版 Mock 服务**:所有接口已上线,但**不做真实算法计算**,统一返回下文「响应示例」中的默认值;所有图片字段均返回示例图 `https://hair.xiangsilian.com/static/sample.jpg`。真实逻辑后续接入。
|
||
|
||
---
|
||
|
||
## 服务地址与接口路径
|
||
|
||
- **Base URL**:`https://hair.xiangsilian.com`
|
||
- **在线接口文档(Swagger)**:`https://hair.xiangsilian.com/docs`
|
||
|
||
| 接口 | 方法 | 路径 |
|
||
|------|------|------|
|
||
| 1 四庭七眼测量 | POST | `/api/v1/face/measure` |
|
||
| 2 C 端生发 | POST | `/api/v1/hair/grow` |
|
||
| 3 B 端生发 | POST | `/api/v1/hair/grow-b` |
|
||
| 4 用户特征 | POST | `/api/v1/face/features` |
|
||
| 5 发际线 PNG 生成 | POST | `/api/v1/hairline/generate` |
|
||
|
||
---
|
||
|
||
## 通用约定
|
||
|
||
以下约定适用于全部 5 个接口(最终以联调为准)。
|
||
|
||
### 请求
|
||
|
||
| 项目 | 约定 |
|
||
|------|------|
|
||
| 协议 | HTTPS |
|
||
| 请求方式 | `POST` |
|
||
| 图片传参方式 | 三选一,三种都支持:① `multipart/form-data` 上传文件、② 图片 URL、③ base64 字符串 |
|
||
| 字符编码 | UTF-8 |
|
||
| 坐标基准 | 所有返回的坐标均以**原图像素**为基准(原点为图片左上角,x 向右、y 向下) |
|
||
|
||
图片传参字段(三者**严格互斥**,必须且只能传其一;传了 0 个或 ≥2 个均报错):
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| image_file | file | 上传文件(`multipart/form-data`) |
|
||
| image_url | string | 图片 URL |
|
||
| image_base64 | string | 图片 base64 字符串,**需带前缀**,如 `data:image/png;base64,xxxx` |
|
||
|
||
### 图片输入要求(接口 1/2/3/4/5 通用)
|
||
|
||
| 项目 | 要求 |
|
||
|------|------|
|
||
| 图片类型 | 用户正面照(人像) |
|
||
| 人脸数量 | 默认仅支持**单人**;若检测到 2 或 3 张人脸(即多人),报错并提示客户端 |
|
||
| 单文件大小 | ≤ 1 MB |
|
||
| 最低分辨率 | 720 × 1024 |
|
||
| 最大分辨率 | 2160 × 3840 |
|
||
| 格式 | 目前仅支持 JPG / PNG |
|
||
|
||
### 统一响应结构
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "success",
|
||
"request_id": "唯一请求标识",
|
||
"data": { }
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| code | int | 0 表示成功,非 0 表示失败 |
|
||
| message | string | 结果描述 / 错误原因 |
|
||
| request_id | string | 请求追踪 ID |
|
||
| data | object | 业务数据,结构见各接口 |
|
||
|
||
### 通用错误码(识别失败时返回,见需求文档)
|
||
|
||
| code | message | 说明 |
|
||
|------|---------|------|
|
||
| 1001 | 无法识别人像 | 图片中未检测到人脸 |
|
||
| 1002 | 人像分辨率过低 | 低于最低分辨率要求 |
|
||
| 1003 | 角度问题,非正面照 | 非正面 / 角度过大 |
|
||
| 1004 | 性别标签判断异常 | 男女标签无法判定 **【待确认】** 是否作为错误 |
|
||
| 1005 | 检测到多张人脸 | 默认仅支持单人,检测到 2 人或以上时返回 |
|
||
| 1006 | 文件超出大小限制 | 单文件超过 1 MB |
|
||
| 1007 | 图片参数错误 | file / url / base64 未传,或同时传了多个(三者严格互斥) |
|
||
| 1008 | 图片格式不支持 | 非 JPG / PNG |
|
||
|
||
---
|
||
|
||
## 接口 1:四庭七眼测量标注接口
|
||
|
||
**说明**:输入用户照片,输出一张标注好四庭七眼数据的 PNG 图片(**不包含人物本体,仅标注图层**),同时返回四庭、七眼的比例与厘米数值。
|
||
|
||
**请求**:`POST /api/v1/face/measure`
|
||
|
||
### 输入
|
||
|
||
图片参数见「通用约定 → 图片传参字段」(`image_file` / `image_url` / `image_base64` 三选一)。本接口无其他专属参数。
|
||
|
||
### 输出(data)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| annotated_image_url | string | 标注好数据的 PNG 图片(仅标注图层,不含人物) |
|
||
| face_total_height_cm | number | 全脸总高度(cm) |
|
||
| four_courts | object | 四庭数据,见下表 |
|
||
| seven_eyes | object | 七眼数据,见下表 |
|
||
| landmarks | object | 关键分界点坐标(头顶 / 发际线 / 眉心 / 鼻翼下缘 / 下巴尖),原图像素坐标 |
|
||
|
||
`four_courts`(四庭,自上而下):
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| top_court_cm | number | 顶庭长度(cm),示例:约占全脸高度 22% |
|
||
| upper_court_cm | number | 上庭长度(cm),约占 25% |
|
||
| middle_court_cm | number | 中庭长度(cm),约占 28% |
|
||
| lower_court_cm | number | 下庭长度(cm),约占 25% |
|
||
| ratios | object | 各庭占全脸高度的百分比 |
|
||
|
||
`seven_eyes`(七眼,横向):
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| eye_width_cm | number | 单眼宽度(cm) |
|
||
| face_width_cm | number | 脸宽(cm) |
|
||
| inter_eye_distance_cm | number | 两眼间距(cm) |
|
||
| ratios | object | 七眼各段占脸宽的比例 |
|
||
|
||
### 标注图片(UI)规范
|
||
|
||
| 项目 | 要求 |
|
||
|------|------|
|
||
| 字体及线颜色 | `#FFFFFF` 100% |
|
||
| 数值排布 | 四庭数值统一在图片**左侧**呈现;七眼间距**上下穿插**展示 |
|
||
| 字体 | PingFangSC-Regular,字号 10pt |
|
||
| 线宽 | 横线、竖线、虚线均为 1pt |
|
||
| 线样式 | 横线、竖线渐变消失;虚线两侧呈现箭头 |
|
||
|
||
> **【待确认】** 标注图片需提供设计稿后才能最终确定样式。
|
||
|
||
### 响应示例(当前 Mock 返回值)
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "success",
|
||
"request_id": "mock-request-id",
|
||
"data": {
|
||
"annotated_image_url": "https://hair.xiangsilian.com/static/sample.jpg",
|
||
"face_total_height_cm": 13.76,
|
||
"four_courts": {
|
||
"top_court_cm": 3.44,
|
||
"upper_court_cm": 3.44,
|
||
"middle_court_cm": 3.44,
|
||
"lower_court_cm": 3.44,
|
||
"ratios": { "top_court": 0.25, "upper_court": 0.25, "middle_court": 0.25, "lower_court": 0.25 }
|
||
},
|
||
"seven_eyes": {
|
||
"eye_width_cm": 3.44,
|
||
"face_width_cm": 24.08,
|
||
"inter_eye_distance_cm": 3.44,
|
||
"ratios": { "eye_width": 0.143, "inter_eye_distance": 0.143 }
|
||
},
|
||
"landmarks": {
|
||
"hair_top": { "x": 540, "y": 120 },
|
||
"hairline": { "x": 540, "y": 430 },
|
||
"brow_center": { "x": 540, "y": 740 },
|
||
"nose_bottom": { "x": 540, "y": 1050 },
|
||
"chin_tip": { "x": 540, "y": 1360 }
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 接口 2:C 端生发接口
|
||
|
||
**说明**:输入用户正面照 + 性别,按性别对应的发际线类型,逐张把建议发际线渲染到照片上,输出多张方案。
|
||
|
||
> **每个方案返回两张图**:`image_url`=「原照片 + 发际线曲线叠加的**预览图**」;`grown_image_url`=
|
||
> 经 ComfyUI/Flux 的「植发 3 个月**生发后图片**」。两者均已实现,见 [`接口2-C端生发-技术实现方案.md`](接口2-C端生发-技术实现方案.md)。
|
||
|
||
**请求**:`POST /api/v1/hair/grow`
|
||
|
||
### 输入
|
||
|
||
图片参数见「通用约定 → 图片传参字段」。专属参数:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| gender | string | **是** | 性别:`male` / `female`。决定使用的发际线贴图集合 |
|
||
| beauty_enabled | bool | 否 | 生发图是否带美颜效果,默认 false(当前阶段不生效) |
|
||
|
||
### 输出(data)
|
||
|
||
`results`:发际线方案数组,**数量 = 该性别的发际线类型数**(`female` 5 个 / `male` 4 个)。每个元素:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| image_url | string | 方案**预览图** URL(发际线曲线叠加图) |
|
||
| grown_image_url | string | **生发后图片** URL(ComfyUI/Flux「植发 3 个月」效果图) |
|
||
| hairline_type | string | 发际线类型 key:`ellipse`/`flower`/`heart`/`straight`/`wave`(female),`ellipse`/`m`/`straight`/`inverse_arc`(male) |
|
||
| order | int | 排序序号(当前阶段固定 `1..N`,按贴图顺序,暂不计算合适度) |
|
||
|
||
> ⚠️ 生发图由本机 ComfyUI(Flux-2,端口 8182)生成,**一次请求生成全部 N 张、同步返回**,
|
||
> 单请求耗时可达数分钟,调用方超时需放大。worker 侧返回 `image_base64` / `grown_image_base64`,
|
||
> 网关落盘后改写为上表的 `image_url` / `grown_image_url`。
|
||
|
||
### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "success",
|
||
"request_id": "mock-request-id",
|
||
"data": {
|
||
"results": [
|
||
{ "image_url": "https://hair.xiangsilian.com/static/annotations/uuid1.png", "grown_image_url": "https://hair.xiangsilian.com/static/annotations/grown1.png", "hairline_type": "ellipse", "order": 1 },
|
||
{ "image_url": "https://hair.xiangsilian.com/static/annotations/uuid2.png", "grown_image_url": "https://hair.xiangsilian.com/static/annotations/grown2.png", "hairline_type": "flower", "order": 2 }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
> 识别失败时返回通用错误码(1001 / 1002 / 1003 等)。`gender` 缺失或非法值返回参数错误(1008);本接口已改为必填入参,不再自动判别性别(1004 不再使用)。
|
||
|
||
---
|
||
|
||
## 接口 3:B 端生发接口
|
||
|
||
**说明**:医生/操作端在用户照片上用马克笔标注目标发际线后,**只需上传这一张划线图**。系统检测划线 →
|
||
据此生成生发后图片。
|
||
|
||
**请求**:`POST /api/v1/hair/grow-b`
|
||
|
||
### 输入
|
||
|
||
划线图片支持「文件 / URL / base64」三选一(字段:`marked_image_file` / `marked_image_url` / `marked_image_base64`)。
|
||
**不需要原始照片**(划线图本身就是用户照片 + 手绘线)。
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| marked_image_* | file / string | 是 | 已用马克笔标注发际线的图片,三选一 |
|
||
|
||
### 输出(data)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| hair_growth_image_url | string | **生发后图片**(检测划线 → ComfyUI/Flux「植发 3 个月」效果)。worker 返回 `hair_growth_image_base64` |
|
||
| hairline_type | string | 发际线形,手绘为定制,固定 `"custom"` |
|
||
|
||
> 未检测到划线(或无人脸)返回 **1001**。
|
||
|
||
### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "success",
|
||
"request_id": "mock-request-id",
|
||
"data": {
|
||
"hair_growth_image_url": "https://hair.xiangsilian.com/static/annotations/grown.png",
|
||
"hairline_type": "custom"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 接口 4:用户特征接口
|
||
|
||
**说明**:输入用户照片,由**火山方舟 豆包视觉模型**(`doubao-seed-1-6-vision`)分析,输出一大批面部特征。
|
||
|
||
**请求**:`POST /api/v1/face/features`
|
||
|
||
### 输入
|
||
|
||
图片参数见「通用约定 → 图片传参字段」。本接口无其他专属参数。
|
||
|
||
### 输出(data)
|
||
|
||
`data.features` 是一个 **JSON 字符串**(不是对象,客户端 `JSON.parse()` 后用)。内含**几十项**特征:
|
||
脸型/眉形/眼型/鼻型/眼袋/法令纹/人中/瞳色/脖长/肤色、三庭五眼、四季色彩季型、量感/轮廓类型、
|
||
直曲量感得分、面部立体度、瞳距、对比度、基因风格、动静类型、性别……字段不固定、可随时增删。
|
||
|
||
其中**英文优先字段**(与 doubao 中文字段并存,方便客户端直接取):
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| face_shape | 脸形(脸型)|
|
||
| eyebrow_shape | 眉形 |
|
||
| facial_age | 面部年龄(区间字符串,如"18-25岁")|
|
||
| dynamic_static_type | 动静类型(静态型/动态型)|
|
||
| gender | 性别(男/女)|
|
||
| gene_style | 基因风格(如"自然型")|
|
||
|
||
> 无人脸返回 `1001`(据 doubao「图片是否有人脸」判定)。⚠️ 本接口是唯一调**外网云模型**的接口,
|
||
> worker 需可访问 `ark.cn-beijing.volces.com`;API Key 走 worker 配置/环境变量。
|
||
|
||
### 响应示例
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "success",
|
||
"request_id": "mock-request-id",
|
||
"data": {
|
||
"features": "{\"图片是否有人脸\":\"有人\",\"脸型\":\"鹅蛋脸\",\"眉形\":\"平眉\",\"面部年龄\":\"18-25岁\",\"四季色彩季型\":\"冷夏型\",\"基因风格\":\"少年型\",\"性别\":\"女\",\"face_shape\":\"鹅蛋脸\",\"eyebrow_shape\":\"平眉\",\"facial_age\":\"18-25岁\",\"dynamic_static_type\":\"静态型\",\"gender\":\"女\",\"gene_style\":\"少年型\"}"
|
||
}
|
||
}
|
||
```
|
||
|
||
> `features` 为字符串形式的 JSON,字段后续可随时增删,不固定。
|
||
|
||
---
|
||
|
||
## 接口 5:发际线 PNG 生成接口
|
||
|
||
**说明**:输入用户照片,返回 N 张用户发际线的 PNG 图片,并返回「最合适发际线」的面部中间点坐标。
|
||
|
||
**请求**:`POST /api/v1/hairline/generate`
|
||
|
||
### 输入
|
||
|
||
图片参数见「通用约定 → 图片传参字段」。专属参数:
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| gender | string | **是** | 性别:`male` / `female`。决定返回的发际线集合(female 5 / male 4) |
|
||
|
||
### 输出(data)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| hairline_images | object[] | N 张发际线叠加图(发际线曲线叠在用户照片上,同接口2预览),**数量 = 该性别发际线数**,本期按贴图顺序,元素见下表 |
|
||
| best_hairline_center_point | object | 最佳(order=1)发际线曲线的「面部中间点」坐标,原图像素:`{ "x": number, "y": number }` |
|
||
|
||
`hairline_images` 元素:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| image_url | string | 发际线叠加图 URL(worker 返回 `image_base64`,网关落盘后改写为 url) |
|
||
| order | int | 排序序号(本期固定 `1..N`,暂不计算合适度) |
|
||
|
||
### 响应示例(当前 Mock 返回值)
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "success",
|
||
"request_id": "mock-request-id",
|
||
"data": {
|
||
"hairline_images": [
|
||
{ "image_url": "https://hair.xiangsilian.com/static/sample.jpg", "order": 1 },
|
||
{ "image_url": "https://hair.xiangsilian.com/static/sample.jpg", "order": 2 }
|
||
],
|
||
"best_hairline_center_point": { "x": 540, "y": 430 }
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 汇总:输入输出一览
|
||
|
||
| 接口 | 输入 | 主要输出 |
|
||
|------|------|----------|
|
||
| 1 四庭七眼测量 | 用户照片 | 标注 PNG(无人物)+ 四庭/七眼厘米数值与坐标 |
|
||
| 2 C 端生发 | 用户照片 | 生发后图片 + 多张发际线(带类型与排序) |
|
||
| 3 B 端生发 | 划线图片 | 最合适发际线图片 + 生发后图片 |
|
||
| 4 用户特征 | 用户照片 | N 个用户特征字段(脸形/眉形/年龄/动静/性别/基因风格…) |
|
||
| 5 发际线 PNG | 用户照片 | N 张发际线 PNG + 最合适发际线面部中间点坐标 |
|
||
|
||
---
|
||
|
||
## 已确认结论
|
||
|
||
- 图片传参:**文件 / URL / base64 三种都支持,严格互斥**(必须且只能传一个,base64 需带 `data:image/...;base64,` 前缀)。
|
||
- 默认单人;检测到 2~3 人报错提示客户端;单文件 **≤ 1 MB**;格式仅 **JPG / PNG**。
|
||
- 所有坐标基准:**原图像素**。
|
||
- 接口 2:提供「美颜」开关 `beauty_enabled`。
|
||
- 接口 3:需同时上传原图,需返回发际线类型。
|
||
- 接口 4:`data` 返回**一个 JSON 字符串**,字段不固定,可随时调整。
|
||
- 接口 5:发际线 PNG 数量 **N 不固定**,需按合适度**排序**。
|
||
- 英文字段命名由本文档约定(见各接口表格)。
|
||
|
||
## 待与需求方确认的问题清单
|
||
|
||
1. 接口 1 标注图片设计稿(见下方说明)。
|