feat: 新增42号人脸特征与72号B端关键点接口

This commit is contained in:
xsl
2026-11-07 20:35:55 +08:00
parent ccb9c142c4
commit c9a47a76c9
16 changed files with 983 additions and 25 deletions
+85
View File
@@ -18,7 +18,9 @@
| 6 四庭七眼测量 v2 | POST | `/api/v1/face/measure-v2` |
| 2 C 端生发 | POST | `/api/v1/hair/grow` |
| 3 B 端生发 | POST | `/api/v1/hair/grow-b` |
| 72 B 端五个关键点 | POST | `/api/v1/face/b-end-points` |
| 4 用户特征 | POST | `/api/v1/face/features` |
| 42号接口-加两个特征点 | POST | `/api/v1/face/features-42` |
| 5 发际线 PNG 生成 | POST | `/api/v1/hairline/generate` |
| 52 发际线新规则与裁切 | POST | `/api/v1/hairline/generate-52` |
@@ -447,6 +449,89 @@ GPU worker的所有动态接口均启用IP限制:允许本机及`ip_access.jso
---
## 接口 72:B 端五个关键点
`POST /api/v1/face/b-end-points` 接受三选一图片参数 `image_file`、`image_url`、`image_base64`。复用接口 52 的扶正裁切与虹膜/眼宽厘米估算,返回坐标以处理后底图为准。
| 点号 | 位置 | 标注 |
|---|---|---|
| 1 | MediaPipe 4 | 白点 |
| 2 | HL center | 白点 |
| 3 | HL center 向画面右侧水平偏移 2 cm | 白点 |
| 4 | HL left | 白点 |
| 5 | HL left left | 白点 |
| 6 | MediaPipe 446 | 白点,兼作射线锚点 |
六个白点的直径相同。标注层包含三条从起点向目标方向延伸并逐渐变淡的白色虚线(2→1、4→6、5→6),以及 2→3 白色虚线段。2→1 射线比默认可见长度短 15%,5→6 射线的绘制长度比默认长度多 30%,可见范围以图像边界为限。四个距离文字分别放在 2–1 中点左侧、2–3 中点上方、4–6 中点左侧和 5–6 中点右侧,距离保留一位小数,2–3 固定显示 `2.0 CM`。
| `data` 字段 | 内容 |
|---|---|
| `input_image_url` | 扶正裁切后的底图 |
| `annotated_image_url` | 与底图同尺寸的透明 PNG 标注层 |
| `points` | 按字符串点号 `"1"` 到 `"6"` 索引的像素坐标 `{x, y}` |
| `measurements_cm` | 四个距离,以 `2-1`、`2-3`、`4-6`、`5-6` 索引 |
| `image_size` | 处理后尺寸 `{width, height}` |
| `coordinate_space` | `processed_image` |
| `px_per_cm` | 估算的每厘米像素数 |
Worker 直连时图片字段使用 `_base64` 后缀。检测不到人脸返回 `1001`,非正面或标注所需点位无法取得时返回 `1003`,图片无法解码返回 `1008`。
---
## 42号接口-加两个特征点
**请求** `POST /api/v1/face/features-42`,使用 `multipart/form-data`。
| 请求字段 | 类型 | 说明 |
|---|---|---|
| `image_file` | 文件 | 上传 JPG 或 PNG |
| `image_url` | 字符串 | 网关可访问的图片 URL |
| `image_base64` | 字符串 | 图片 Base64,支持带 `data:image/…;base64,` 前缀 |
以上三个字段必须且只能传一个。图片按 EXIF 方向解码后,先检查原图的人脸完整性和俯拍角度。俯拍使用头部姿态估算的正向 pitch,超过服务端环境变量 `FRONTAL_PITCH_THR`(默认 30°)时拦截。通过质检后复用接口 52 的扶正裁切规则,再用处理后的图片做面部特征分析。
### 质检失败与异常响应
以下业务响应的 HTTP 状态均为 `200`。
| `code` | 情况 | `message` |
|---|---|---|
| `1001` | 原图未检测到人脸 | 无法识别人像,请上传包含完整人脸的照片 |
| `1003` | 人脸关键点触及或超出图片边界 | 人脸不完整,请保留完整的脸部轮廓 |
| `1003` | 估算的俯拍角度超过阈值 | 俯拍角度过大,请将相机调整至与脸部平视 |
| `1003` | 扶正裁切失败,无法保留所需人脸关键点 | 人脸过于贴近边缘,无法扶正裁切 |
| `1008` | URL 图片下载失败 | 图片下载失败(URL 不可达) |
| `1008` | Base64 解码失败 | 图片格式不支持(base64 解码失败) |
| `1008` | 图片无法读取 | 图片格式不支持(仅 JPG / PNG) |
| `1007` | 图片字段未按三选一传入 | 图片参数错误:必须且只能传 image_file / image_url / image_base64 其中一个 |
| `1007` | 图片预处理内部异常 | 图片预处理失败 |
| `1001` | 质检通过,但视觉模型未识别到人脸 | 无法识别人像 |
| `1007` | 视觉模型调用异常 | 分析服务异常:… |
响应包含 `code`(整数业务码)、`message`(字符串提示)、`request_id`(字符串请求标识)和 `data`(失败时为 `null`)。三个 `1003` 情况可通过 `message` 区分,响应中没有独立的质检原因或角度字段。
```json
{
"code": 1003,
"message": "俯拍角度过大,请将相机调整至与脸部平视",
"request_id": "gw-xxxxxxxx",
"data": null
}
```
### 成功响应
`data.features` 仍为 JSON 字符串,保留接口 4 的六项特征,在其中新增:
| 字段 | 类型 | 说明 |
|------|------|------|
| `zygoma_expansion` | boolean 或 null | 颧弓外扩 |
| `temple_hollowing` | boolean 或 null | 太阳穴凹陷 |
Ft 两端保持横坐标并取平均高度,Zy 为 234 到 454 的距离。只有 Ft ÷ Zy 严格小于 0.8 时两项同时为 `true`,否则同时为 `false`。所需点位缺失或无法测量时两项均为 `null`。网关测量复用接口 99 的 MediaPipe 与 BiSeNet 依赖,裁切还需要 Pillow。
---
## 接口 5:发际线 PNG 生成接口
**说明**:入参同接口2(先选性别、再多选发型)。对每个选中发型返回 `middle` / `high` / `low` **三档**发际线叠图与**生发图**,并返回「最合适发际线」的面部中间点坐标。