# 发型补全服务 API 文档 ## 服务概述 本服务提供基于 ComfyUI 的发型补全(局部重绘)能力。通过传入人物图片和遮罩图片,调用 ComfyUI 工作流(`0716add-hair.json`)生成补全后的图片。 ## 技术栈 - **框架**: Flask - **依赖**: requests, Pillow, numpy - **后端**: ComfyUI (http://127.0.0.1:8188) ## 服务地址 - **HTTP**: `http://127.0.0.1:8899` - **前端页面**: `http://127.0.0.1:8899/` - **API接口**: `http://127.0.0.1:8899/api/generate` ## 启动方式 ### 使用脚本(推荐) ```bash # 启动服务 cd /home/ubuntu/hair/local_test ./start.sh # 停止服务 ./stop.sh ``` ### 直接运行 ```bash cd /home/ubuntu/hair/local_test /home/ubuntu/ComfyUI/venv/bin/python app.py ``` ## API 接口 ### POST /api/generate 调用 ComfyUI 工作流,传入图片和遮罩,返回生成结果。 #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | image | File | 是 | 人物图片(支持 jpg, png 等常见格式) | | mask | File | 是 | 遮罩图片(支持 jpg, png,遮罩区域可用红色/白色/alpha 通道标识) | | prompt | String | 否 | 提示词,默认值:"填充遮罩区域的头发" | #### 遮罩图片格式说明 服务支持多种遮罩格式,自动提取遮罩区域: | 格式类型 | 示例 | 遮罩区域标识 | |----------|------|--------------| | 红色遮罩 | 红色画笔绘制 | R=255 的像素 | | 白色遮罩 | 白色画笔绘制 | R=G=B=255 的像素 | | Alpha 遮罩 | 透明背景 | A=255 的像素 | 服务会取所有通道的最大值作为遮罩强度,因此以上格式均可混用。 **注意**: 遮罩区域表示需要重绘的部分,非遮罩区域保持原图不变。 #### 请求示例(curl) ```bash curl -X POST http://127.0.0.1:8899/api/generate \ -F "image=@/path/to/person.jpg" \ -F "mask=@/path/to/mask.png" \ -F "prompt=填充遮罩区域的头发" \ --output result.png ``` #### 请求示例(Python) ```python import requests url = "http://127.0.0.1:8899/api/generate" files = { "image": open("person.jpg", "rb"), "mask": open("mask.png", "rb"), } data = { "prompt": "填充遮罩区域的头发" } resp = requests.post(url, files=files, data=data, timeout=600) if resp.status_code == 200: with open("result.png", "wb") as f: f.write(resp.content) else: print(f"Error: {resp.json()}") ``` #### 响应 **成功 (HTTP 200)**: 返回 PNG 图片二进制数据,Content-Type: `image/png`。 **失败 (HTTP 4xx/5xx)**: 返回 JSON 格式错误信息: ```json { "error": "错误描述" } ``` #### 错误码 | 状态码 | 说明 | |--------|------| | 500 | 内部错误(文件处理失败、ComfyUI 返回错误等) | | 503 | 无法连接到 ComfyUI(服务未启动或端口错误) | | 500 | 超时(工作流执行超过 5 分钟) | ## 工作流说明 服务使用的工作流 `0716add-hair.json` 包含以下处理步骤: 1. **加载模型**: Flux 2 Klein 9B (FP8) + Qwen 3.8B CLIP 2. **图片上传**: 将原图与遮罩合成为 RGBA 格式上传至 ComfyUI 3. **遮罩处理**: 填充孔洞 → 转换为图像 → 缩放 → 转换回遮罩 4. **图像缩放**: 按比例缩放至合适尺寸(最大边长 1024,8 的倍数) 5. **VAE 编码**: 将图像编码为 latent 6. **采样生成**: 使用 Flux 模型 + ReferenceLatent 进行局部重绘 7. **VAE 解码**: 将 latent 解码为图像 8. **颜色匹配**: 使用 ColorMatch 保持颜色一致 9. **保存结果**: 返回生成的图片 ## 前置依赖 启动服务前需确保: 1. **ComfyUI 已启动**: `http://127.0.0.1:8188` 可访问 2. **模型文件存在**: - `models/unet/flux2.0/flux-2-klein-9b-fp8.safetensors` - `models/vae/flux2-vae.safetensors` - `models/clip/qwen_3_8b_fp8mixed.safetensors` 3. **虚拟环境已激活**: 使用 `/home/ubuntu/ComfyUI/venv/bin/python` ## 文件结构 ``` /home/ubuntu/hair/local_test/ ├── app.py # Flask 后端服务 ├── index.html # 前端测试页面 ├── test_api.py # API 测试脚本 ├── README.md # 本文档 ├── output/ # 测试结果输出目录 ├── 用来重绘.jpg # 测试人物图片 └── 用来重绘.png # 测试遮罩图片 ``` ## 使用流程 1. 启动 ComfyUI(`python main.py --listen`) 2. 启动本服务(`python app.py`) 3. 调用 API 或访问前端页面上传图片和遮罩 4. 等待生成完成(通常 30-60 秒) 5. 获取返回的 PNG 图片 ## 注意事项 - 请求超时时间为 5 分钟,生成复杂图片可能需要较长时间 - 遮罩图片尺寸需与人物图片一致,服务会自动缩放对齐 - 建议使用红色或白色绘制遮罩,确保遮罩强度足够 - 服务会自动对遮罩边缘进行高斯模糊(radius=4),避免硬边