feat(接口6): 复刻接口1,新增 /api/v1/face/measure-v2
- 抽取 _face_measure_impl() 共用实现,接口1/6 零逻辑差异 - 接口6 路径 POST /api/v1/face/measure-v2 - 入参/出参与接口1 完全一致 - 文档同步更新(接口文档、实现说明、网关待改动) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+7
-1
@@ -13,7 +13,7 @@
|
||||
```
|
||||
客户端 ──HTTPS──> 外网网关(gateway/) ──HTTP(X-Internal-Token)──> worker(GPU 机, app.py)
|
||||
│ 薄代理 + 落盘改URL │ 跑算法(本地模型/ComfyUI)
|
||||
└ 接口4 本机直接调豆包(不转发) └ 接口1/2/3/5/7
|
||||
└ 接口4 本机直接调豆包(不转发) └ 接口1/2/3/5/6/7
|
||||
```
|
||||
|
||||
- **worker**(`app.py` + `face_analysis/` + `hairline/`):跑真正的算法,**纯本地、无外网依赖**。
|
||||
@@ -29,6 +29,7 @@
|
||||
| 接口 | worker 字段(内部) | 对外字段 |
|
||||
|------|--------------------|----------|
|
||||
| 1 | `annotated_image_base64` | `annotated_image_url` |
|
||||
| 6 | `annotated_image_base64` | `annotated_image_url` |
|
||||
| 2 | `results[].image_base64` / `results[].grown_image_base64`(可空) | `results[].image_url` / `results[].grown_image_url` |
|
||||
| 3 | `hair_growth_image_base64`(可空) | `hair_growth_image_url` |
|
||||
| 5 | `hairline_images[].image_base64` | `hairline_images[].image_url` |
|
||||
@@ -55,6 +56,11 @@
|
||||
失败回退比例推算(方案A,`hairline_source` 透出)。标注图 numpy 向量化渐变线 + 思源黑体。返回 `annotated_image_base64`。
|
||||
- 门槛可配:`MIN_SHORT_SIDE`/`MIN_LONG_SIDE`(默认600/800)、姿态阈值 `FRONTAL_*_THR`(默认30°)。
|
||||
|
||||
### 接口6 四庭七眼测量 v2 `/api/v1/face/measure-v2`(worker)—— 复刻接口1
|
||||
- **做什么**:与接口 1 完全一致(正面照 → 四庭七眼 cm 与占比 + 5 个关键点 + 标注 PNG)。
|
||||
- **怎么实现**:与接口 1 共用 `_face_measure_impl()`,零额外逻辑。对外路径 `/api/v1/face/measure-v2`。
|
||||
- **网关改动**:新增路由 `POST /api/v1/face/measure-v2`,转发到 worker 同路径;base64→URL 改写无需改动。
|
||||
|
||||
### 接口2 C端生发 `/api/v1/hair/grow`(worker)—— 预览 + 生发图
|
||||
- **做什么**:正面照 + `gender`(必填) + `hair_style`(必填,逗号分隔多选,如 `1,2,3`) → 指定发际线类型 **N 组**:**预览图**(发际线叠在照片上) + **生发后图**(植发3个月效果)。
|
||||
- **怎么实现**(`hairline/`):移植 head3d——MediaPipe(Tasks) + SegFormer 分割 + 17 锚点射线检测 → 502 点 mesh,
|
||||
|
||||
+54
-1
@@ -15,6 +15,7 @@
|
||||
| 接口 | 方法 | 路径 |
|
||||
|------|------|------|
|
||||
| 1 四庭七眼测量 | POST | `/api/v1/face/measure` |
|
||||
| 6 四庭七眼测量 v2 | POST | `/api/v1/face/measure-v2` |
|
||||
| 2 C 端生发 | POST | `/api/v1/hair/grow` |
|
||||
| 3 B 端生发 | POST | `/api/v1/hair/grow-b` |
|
||||
| 4 用户特征 | POST | `/api/v1/face/features` |
|
||||
@@ -176,6 +177,57 @@
|
||||
|
||||
---
|
||||
|
||||
## 接口 6:四庭七眼测量 v2 接口
|
||||
|
||||
**说明**:功能与[接口 1](#接口-1四庭七眼测量标注接口)完全一致,复刻实现。输入用户正面照,返回四庭七眼测量数据和标注 PNG。
|
||||
|
||||
**请求**:`POST /api/v1/face/measure-v2`
|
||||
|
||||
### 输入
|
||||
|
||||
与接口 1 完全相同。图片参数见「通用约定 → 图片传参字段」(`image_file` / `image_url` / `image_base64` 三选一)。本接口无其他专属参数。
|
||||
|
||||
### 输出(data)
|
||||
|
||||
与接口 1 完全相同。详见[接口 1 输出](#接口-1四庭七眼测量标注接口)。
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| annotated_image_url | string | 标注图层 PNG URL(透明底,仅标注线/文字,不含人物) |
|
||||
| face_total_height_cm | number | 面部总高度(cm) |
|
||||
| four_courts | object | 四庭数据(顶庭/上庭/中庭/下庭,各含 cm 与 ratio) |
|
||||
| seven_eyes | object | 七眼数据(眼宽/脸宽/两眼间距,各含 cm 与 ratio) |
|
||||
| landmarks | object | 五个关键点像素坐标 |
|
||||
|
||||
### 响应示例
|
||||
|
||||
```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 端生发接口
|
||||
|
||||
**说明**:输入用户正面照 + 性别 + 发型序号(可多选),按指定发际线类型渲染预览图 + 生发图。
|
||||
@@ -421,7 +473,8 @@
|
||||
| 接口 | 输入 | 主要输出 |
|
||||
|------|------|----------|
|
||||
| 1 四庭七眼测量 | 用户照片 | 标注 PNG(无人物)+ 四庭/七眼厘米数值与坐标 |
|
||||
| 2 C 端生发 | 用户照片 | 生发后图片 + 指定发际线预览(单张) |
|
||||
| 6 四庭七眼测量 v2 | 用户照片 | 同接口1,复刻实现 |
|
||||
| 2 C 端生发 | 用户照片 | 生发后图片 + 指定发际线预览(单/多张) |
|
||||
| 3 B 端生发 | 划线图片 | 最合适发际线图片 + 生发后图片 |
|
||||
| 4 用户特征 | 用户照片 | 6 个用户特征字段(脸形/眉形/年龄/动静/性别/基因风格) |
|
||||
| 5 发际线 PNG | 用户照片 | N 张发际线 PNG + 最合适发际线面部中间点坐标 |
|
||||
|
||||
@@ -109,6 +109,30 @@ async def hair_grow_v2(request: Request):
|
||||
|
||||
若想让网关 `/docs` 展示准确,在 `gateway/app.py` 新增 `_GROW_V2_FORMS`(或复用 `_GROW_FORMS` 并补充 `gender`/`hair_style` 字段),然后将路由函数签名改为显式声明 Form 参数(参考接口 4 的写法)。不改也不影响实际转发。
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 6. 🔲【新增】接口6 四庭七眼测量 v2(`/api/v1/face/measure-v2`)
|
||||
|
||||
**背景**:worker 侧已新增接口 6,功能与接口 1 完全一致(复刻),共用同一实现。
|
||||
|
||||
**网关需新增一个路由**:
|
||||
|
||||
```python
|
||||
# gateway/app.py
|
||||
|
||||
@app.post("/api/v1/face/measure-v2", tags=["人脸分析"])
|
||||
async def face_measure_v2(request: Request):
|
||||
"""接口6:四庭七眼测量 v2(复刻接口1)"""
|
||||
return await _proxy(request, "/api/v1/face/measure-v2")
|
||||
```
|
||||
|
||||
**无需额外改动**:
|
||||
- 入参:与接口 1 完全相同(image_file/url/base64 三选一)
|
||||
- 出参:`annotated_image_base64` → 经现有 `rewrite_base64_to_url` 自动改写为 `annotated_image_url`
|
||||
- worker 侧与接口 1 共用 `_face_measure_impl()`,逻辑零差异
|
||||
|
||||
---
|
||||
|
||||
## 已经做好、无需再动的
|
||||
|
||||
Reference in New Issue
Block a user