Files
face_sdk/python/README.md
T
2026-05-05 21:44:42 +08:00

4.3 KiB
Raw Blame History

Face SDK Web 服务

把 Android Face SDK 的人脸贴图渲染逻辑迁移到 Python Web 服务:上传一张人物图 + 效果 ID, 返回叠加渲染后的 PNG。CPU 实现(OpenCV 仿射 warp + alpha 混合),不依赖 GPU。


渲染原理(与 Android SDK 一致)

input image ──► MediaPipe FaceLandmarker ──► 478 normalized landmarks
                                                     │
                                                     ▼
   face_picture_3dmax.obj (468 顶点+UV / 852 三角形)
   每个 obj 顶点 i 的画面位置 = landmarks[INDEX_MAP[i]]
                                                     │
                                                     ▼
   每个三角形:
     src = obj UV × effect 贴图尺寸 (在 512×512 effect 里)
     dst = landmarks 像素位置          (在 input image 里)
     cv2.getAffineTransform → cv2.warpAffine → alpha 混合
                                                     │
                                                     ▼
                                          output PNG(同原图尺寸)

INDEX_MAP[468] 同步自 vulkan/hardcode_data.h::indexMapUV 的 V 翻转与 vulkan/FaceApp.cpp::LoadOBJ 行为一致。


目录结构

python/
├── server/
│   ├── main.py             FastAPI 入口(/health /effects /render
│   ├── face_renderer.py    渲染核心
│   ├── mesh.py             OBJ 解析
│   ├── index_map.py        OBJ vertex → MediaPipe landmark 映射
│   ├── assets/
│   │   ├── face_picture_3dmax.obj   ← 来自 app/src/main/assets
│   │   └── face_landmarker.task     ← 可选;不放则自动回退到 app/src/main/assets/
│   └── effects/
│       └── 1.png           512×512 RGBA 效果贴图,文件名是效果 ID1-99
└── requirements.txt

一次性安装

需要 Python 3.103.12mediapipe 当前不支持 3.13)。

# Windows PowerShell(或 cmd
cd D:\face_sdk\python
python -m venv venv
.\venv\Scripts\Activate.ps1     # cmd 用 .\venv\Scripts\activate.bat
pip install --upgrade pip
pip install -r requirements.txt
# Linux / macOS
cd /path/to/face_sdk/python
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

启动服务

cd D:\face_sdk\python
.\venv\Scripts\Activate.ps1
uvicorn server.main:app --host 0.0.0.0 --port 8000

启动日志看到 Application startup complete. 即就绪。


API

GET /health

{"ok": true}

GET /effects

返回当前 server/effects/ 下存在的效果 ID(按 <id>.png 文件名提取,199):

{"effects": [1]}

POST /render

  • form-data
    • image: 文件(jpeg / png / webp,≤ 20MB
    • effect_id: 整数(199,必须在 /effects 列表内)
  • 成功:200Content-Type: image/pngbody 是 PNG 字节
  • 没检测到人脸:400 {"error":"no_face"}
  • effect_id 不存在:404
  • 参数错误(图非法 / 太大 / id 越界):400

curl 示例

curl -X POST http://localhost:8000/render \
  -F image=@/path/to/photo.jpg \
  -F effect_id=1 \
  --output result.png

Python 示例

import requests
files = {"image": open("photo.jpg", "rb")}
data = {"effect_id": 1}
r = requests.post("http://localhost:8000/render", files=files, data=data)
r.raise_for_status()
open("result.png", "wb").write(r.content)

添加新效果

把一张 512×512 的 RGBA PNG 放到 python/server/effects/<id>.png<id> 是 1–99 的整数)。 服务下次响应 /effects 时会自动列出;首次被请求时按需载入并缓存内存。

PNG 必须有 alpha 通道——透明区域不会盖到原图上。


已知限制

  • 纯 2D 仿射 warp,与 Android SDK 行为一致:人脸侧面角度大时贴图会拉伸。
  • MediaPipe FaceLandmarker 每次 detect() 不保证多线程并发安全,服务用锁串行化。 单进程同步部署够用;要更高并发请用多 worker 或前置队列。
  • 单张 4K 图渲染约 100300ms852 三角形 × cv2.warpAffine);如需更快可改成 cv2.remap 一次性贴整脸,但需要更多代码。