# 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::indexMap`,UV 的 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 效果贴图,文件名是效果 ID(1-99) └── requirements.txt ``` --- ## 一次性安装 需要 Python 3.10–3.12(mediapipe 当前不支持 3.13)。 ```powershell # 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 ``` ```bash # 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 ``` --- ## 启动服务 ```powershell 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` ```json {"ok": true} ``` ### `GET /effects` 返回当前 `server/effects/` 下存在的效果 ID(按 `.png` 文件名提取,1–99): ```json {"effects": [1]} ``` ### `POST /render` - form-data: - `image`: 文件(jpeg / png / webp,≤ 20MB) - `effect_id`: 整数(1–99,必须在 `/effects` 列表内) - 成功:`200`,`Content-Type: image/png`,body 是 PNG 字节 - 没检测到人脸:`400 {"error":"no_face"}` - effect_id 不存在:`404` - 参数错误(图非法 / 太大 / id 越界):`400` #### curl 示例 ```bash curl -X POST http://localhost:8000/render \ -F image=@/path/to/photo.jpg \ -F effect_id=1 \ --output result.png ``` #### Python 示例 ```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/.png`(`` 是 1–99 的整数)。 服务下次响应 `/effects` 时会自动列出;首次被请求时按需载入并缓存内存。 PNG 必须有 alpha 通道——透明区域不会盖到原图上。 --- ## 已知限制 - 纯 2D 仿射 warp,与 Android SDK 行为一致:人脸侧面角度大时贴图会拉伸。 - MediaPipe FaceLandmarker 每次 `detect()` 不保证多线程并发安全,服务用锁串行化。 单进程同步部署够用;要更高并发请用多 worker 或前置队列。 - 单张 4K 图渲染约 100–300ms(852 三角形 × `cv2.warpAffine`);如需更快可改成 `cv2.remap` 一次性贴整脸,但需要更多代码。