ADD MANDARIN README
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# BgFilter
|
||||
|
||||
> 中文: [README_ZH.md](README_ZH.md)
|
||||
|
||||
Offline character matting for AI-generated images on a flat-colour background.
|
||||
The background colour is **auto-detected** from the image border (green, pastel, any
|
||||
flat colour); pass `--screen-color` to set it explicitly.
|
||||
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
# BgFilter
|
||||
|
||||
> English: [README.md](README.md)
|
||||
|
||||
面向"纯色背景 AI 生成图"的离线人物抠图。背景色会**从图像边框自动探测**(绿色、
|
||||
淡彩、任意纯色);也可用 `--screen-color` 显式指定。
|
||||
|
||||
```text
|
||||
RGB 输入
|
||||
-> chroma 背景置信度(按自动探测或指定的颜色打分)
|
||||
-> [可选] 语义分割 mask
|
||||
-> trimap -> ViTMatte -> alpha 清理
|
||||
-> 交叉模型否决(对背景色调残留做第二意见)
|
||||
-> pymatting 前景估计 -> despill 去溢色 -> RGBA PNG -> QA 预览
|
||||
```
|
||||
|
||||
## 管线
|
||||
|
||||
两条管线,由配置里的 `segmentation.enabled` 选择:
|
||||
|
||||
- **仅 Chroma**(`enabled: false`)—— Chroma + ViTMatte,无分割模型。最轻/最快;
|
||||
完全靠颜色键决定拓扑。
|
||||
- **单分割器**(`enabled: true`,默认)—— 一个分割模型定 trimap 拓扑(镂空、发丝),
|
||||
ViTMatte 再细化软边。后端可切换:`birefnet`(默认,通用显著目标——文字、logo、
|
||||
照片;需 `trust_remote_code`)或 `anime-seg`(ONNX,专为动漫角色调优)。运行时用
|
||||
`--seg-backend anime-seg` 切换(会同时选好对应权重)。
|
||||
|
||||
两条管线都共用 pymatting 前景估计和一次颜色 de-spill。**没有**染绿修复 / recolour
|
||||
层——源图干净时它没必要,已移除。
|
||||
|
||||
两条管线**默认都跑交叉模型否决**:第二个、无需 trimap 的抠图模型
|
||||
(`ZhengPeng7/BiRefNet_HR-matting`)只能*降低* alpha,且只作用于主结果自信、
|
||||
但偏背景色调的亮像素——用来清掉卡在发丝间、被 chroma、分割器和 ViTMatte 都误判为
|
||||
前景的偏色背景残留。代价是多下一个模型(~0.9 GB)+ 每图一次额外推理;用
|
||||
`--no-cross-check` 关闭(见 `cross_check` 配置段,分析见 `docs/hair_gap_artifacts.md`)。
|
||||
|
||||
开启交叉否决时,那趟 HR-matting 前向可以选择性地**兼作分割 mask**
|
||||
(`--cross-check-as-seg`),从而完全跳过主分割模型(少加载一个模型,CPU 上每图约快
|
||||
20 s,GPU 上省约 1 GB 显存)。已试点验证(TestImage3 / FixImage1):trimap 99.8% 一致,
|
||||
手指、发丝、细线无结构性变化。**默认关闭**:专用分割器保留自己的前向,否决作为独立
|
||||
的第二信号。该复用是同族替换,故**仅**对 `birefnet` 后端生效:用
|
||||
`--seg-backend anime-seg` 时动漫分割器始终保留自己的前向。
|
||||
|
||||
分割 trimap 默认走 `directional` 模式(chroma + seg + 色调方向切分:保留白衬衫这类
|
||||
背景色系的衣物,同时丢弃卡在发丝间的偏背景色残留如蓝色)。可切换
|
||||
`--trimap-mode seg`(仅拓扑,无色调切分)或 `directional-hard-bg`(激进——硬删偏背景
|
||||
色像素;可能吃掉冷色/阴影下的白布)。
|
||||
|
||||
## 背景色
|
||||
|
||||
默认(`screen_color: null`)背景色**从图像边框自动探测**:边框条带的主导纯色成为键色。
|
||||
若边框不是单一干净纯色——渐变、纹理、或主体占满画面——探测会**报错**;此时请显式传
|
||||
`--screen-color`。
|
||||
|
||||
要自己指定,给一个十六进制先验:
|
||||
|
||||
```powershell
|
||||
... --screen-color "#CFEFFF"
|
||||
```
|
||||
|
||||
或在配置里写 `screen_color: "#CFEFFF"`。无论哪种,chroma 键都按到该颜色的感知
|
||||
(Lab/RGB)距离给像素打分,de-spill 沿该颜色方向压掉色度。(显式给的 hex 会用附近边框
|
||||
像素做微调;自动探测的颜色直接使用。)
|
||||
|
||||
## 环境
|
||||
|
||||
使用 conda 环境 `lightML`。
|
||||
|
||||
```powershell
|
||||
conda activate lightML
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
若未激活 shell,直接调用该环境的 Python:
|
||||
|
||||
```powershell
|
||||
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli --help
|
||||
```
|
||||
|
||||
## 单张图
|
||||
|
||||
```powershell
|
||||
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
|
||||
--input Samples\TestImage.png `
|
||||
--output Outputs\TestImage_rgba.png `
|
||||
--debug-dir Outputs\TestImage_debug
|
||||
```
|
||||
|
||||
无需 `--config`——内置默认值与 `configs/default.yaml` 完全一致。只有当你编辑了该文件
|
||||
去调细节参数时,才需要 `--config configs\default.yaml`。运行时选择留在命令行:
|
||||
`--device`(默认 **CPU**;GPU 用 `--device cuda`)、`--precision`(默认 `fp32`;`bf16`
|
||||
给三个模型加速、并把抠图模型的激活显存减半,alpha 视觉上一致——需 bf16 硬件,否则回落
|
||||
fp32;大输入还会默认对 ViTMatte 全局注意力按 query 分块——精确、逐比特相同,把 2048x2048
|
||||
的内存尖峰从 ~19 GB 压到 ~4 GB,见 `model.attn_query_chunk`)、`--seg-backend`
|
||||
(默认 `birefnet`;动漫角色用 `anime-seg`)、`--screen-color`(默认:自动探测纯背景)、
|
||||
以及 `--trimap-mode`。
|
||||
|
||||
## 批量
|
||||
|
||||
```powershell
|
||||
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
|
||||
--input-dir Samples `
|
||||
--output-dir Outputs `
|
||||
--debug-dir Outputs\debug
|
||||
```
|
||||
|
||||
## 性能(CPU 参考数据)
|
||||
|
||||
在 Ryzen 9700X(Zen 5,原生 bf16)、32 GB 内存上实测,cross-check 开启、
|
||||
**`--cross-check-as-seg` 开启**、分块全局注意力开启。(本分支默认关闭复用;不开的话要
|
||||
加上主 BiRefNet@1024 前向——在这些尺寸下每图约 +20 s。)
|
||||
|
||||
| 输入 | 精度 | warm / 每图 | 峰值内存 |
|
||||
|---|---|---|---|
|
||||
| 1024x1536 | fp32 | ~45 s | — |
|
||||
| 1024x1536 | bf16 | ~33 s | — |
|
||||
| 2048x2048 | bf16 | ~53 s | 11.4 GB(批处理)、8.1 GB(单图) |
|
||||
|
||||
内存上限来自 cross-check 的 BiRefNet_HR 前向(无论图多大都固定 `input_size` 2048)——
|
||||
一个全分辨率密集预测网络的真实活跃激活。在分块注意力和 mimalloc 修复之前,同一个
|
||||
2048x2048 bf16 run 峰值 25.2 GB;完全未优化的 fp32 run 估计要 55-60 GB(单是 ViTMatte
|
||||
未分块的 N^2 注意力就 ~39 GB)。无原生 bf16 的 CPU(如 Zen 2)会自动回落 fp32——这类
|
||||
机器上若内存或延迟紧张,优先 `--no-cross-check`。
|
||||
|
||||
## Chroma-alpha 调试模式
|
||||
|
||||
`--matting-method chroma` 跳过 ViTMatte,直接用 chroma 置信度作为 alpha 种子。适合快速
|
||||
检查 chroma 置信度、trimap 和 despill。(不同于上面的仅 Chroma *管线*,后者仍跑 ViTMatte。)
|
||||
|
||||
```powershell
|
||||
D:\MiniConda\envs\lightML\python.exe -m bgfilter.cli `
|
||||
--input-dir Samples `
|
||||
--output-dir Outputs\chroma `
|
||||
--debug-dir Outputs\chroma_debug `
|
||||
--matting-method chroma `
|
||||
--device cpu
|
||||
```
|
||||
|
||||
## 输出
|
||||
|
||||
每处理一张图,CLI 写一张 RGBA PNG 和可选的调试文件:
|
||||
|
||||
```text
|
||||
bg_confidence.png
|
||||
trimap.png
|
||||
seg_mask.png # 仅分割管线
|
||||
alpha.png
|
||||
foreground_rgb.png # 去溢色后的前景颜色
|
||||
color_mask.png # 逐像素 despill 权重
|
||||
preview_black.png
|
||||
preview_white.png
|
||||
preview_gray.png
|
||||
preview_red.png
|
||||
preview_blue.png
|
||||
qa_grid.png
|
||||
metadata.json
|
||||
```
|
||||
|
||||
## HTTP 服务
|
||||
|
||||
一个 HTTP 封装(`app.py` + `bgfilter/service.py`)把管线暴露为常驻 FastAPI 服务。模型
|
||||
只加载一次、跨请求复用。部署到 Linux 服务器(依赖、权重、systemd、离线模式、鉴权)见
|
||||
[DEPLOY_ZH.md](DEPLOY_ZH.md)。
|
||||
|
||||
```bash
|
||||
python -m uvicorn app:app --host 127.0.0.1 --port 18083 --workers 1
|
||||
```
|
||||
|
||||
单 worker 运行(`--workers 1`)—— 每个 worker 各自加载一份模型。
|
||||
|
||||
### 端点
|
||||
|
||||
- **`GET /healthz`** —— 存活 + 配置 JSON,例如
|
||||
`{"ok":true,"service":"bgfilter","version":"0.1.0","defaultSegModel":"birefnet","device":"cpu","crossCheck":true}`。
|
||||
始终免鉴权。
|
||||
- **`POST /remove-background`** —— 入参 `multipart/form-data`,返回 `image/png`(RGBA)。
|
||||
|
||||
### 鉴权
|
||||
|
||||
可选、按需开启,由环境变量 `BGFILTER_AUTH_TOKEN` 控制。设置后,`/remove-background`
|
||||
要求 header **`X-Genarrative-Image-Token: <token>`**(常量时间比较);缺失或错误返回
|
||||
`401`。不设时端点开放(预期由前置代理鉴权)。`/healthz` 始终开放。见
|
||||
[DEPLOY_ZH.md](DEPLOY_ZH.md) §10。
|
||||
|
||||
### 请求字段(`POST /remove-background`,`multipart/form-data`)
|
||||
|
||||
| 字段 | 必填 | 取值 | 含义 |
|
||||
| --- | --- | --- | --- |
|
||||
| `file` | 是 | 图片文件 | 源图(字段名固定为 `file`)。 |
|
||||
| `screen_color` | 否 | `#RRGGBB`,或留空/`auto` | 背景色先验;留空则从边框自动探测。 |
|
||||
| `seg_model` | 否 | `birefnet`(默认)/ `anime-seg` | 分割后端。 |
|
||||
| `cross_check` | 否 | `1`/`0`(也接受 `true`/`false`/`yes`/`no`/`on`/`off`) | 按请求覆盖交叉否决;留空 = 服务端默认。 |
|
||||
|
||||
### 响应头(`200` 时)
|
||||
|
||||
| 头 | 示例 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `X-BGFilter-Elapsed-Ms` | `2372` | 服务端处理耗时(ms)。 |
|
||||
| `X-BGFilter-Seg-Model` | `birefnet` | 实际使用的分割器。 |
|
||||
| `X-BGFilter-Screen-Color` | `#CFEFFF` / `auto` | 实际使用的背景色。 |
|
||||
| `X-BGFilter-Cross-Check` | `on` / `off` | 本次实际的 cross-check 状态。 |
|
||||
|
||||
### 状态码
|
||||
|
||||
| 码 | 何时 |
|
||||
| --- | --- |
|
||||
| `200` | 成功——响应体是 RGBA PNG。 |
|
||||
| `400` | 输入有误:图片无法解码,`screen_color`/`seg_model`/`cross_check` 非法,或自动探测失败(请传 `screen_color`)。 |
|
||||
| `401` | 鉴权已开且 token 缺失或错误。 |
|
||||
| `413` | 图片超过 `BGFILTER_MAX_IMAGE_PIXELS`(默认约 4 MP)。 |
|
||||
| `500` | 推理失败。 |
|
||||
| `503` | 服务仍在加载模型(未就绪)。 |
|
||||
|
||||
### 示例
|
||||
|
||||
```bash
|
||||
# 默认(birefnet + 自动背景色);若服务要求鉴权则加上 auth header
|
||||
curl -sS -F "file=@input.png" \
|
||||
-H "X-Genarrative-Image-Token: <token>" \
|
||||
http://127.0.0.1:18083/remove-background -o output.png
|
||||
|
||||
# 显式背景色 + 动漫分割器,本次关闭 cross-check
|
||||
curl -sS \
|
||||
-F "file=@input.png" \
|
||||
-F "screen_color=#CFEFFF" \
|
||||
-F "seg_model=anime-seg" \
|
||||
-F "cross_check=off" \
|
||||
http://127.0.0.1:18083/remove-background -o output.png
|
||||
```
|
||||
|
||||
配置来自 `BGFILTER_CONFIG`(存在时默认 `configs/default.yaml`);`BGFILTER_DEVICE` 同时
|
||||
覆盖 model 和 segmentation 的 device;`BGFILTER_MAX_IMAGE_PIXELS` 限制输入尺寸
|
||||
(默认约 4MP → `413`);`BGFILTER_PRELOAD=1` 启动时预加载默认模型;`BGFILTER_AUTH_TOKEN`
|
||||
控制端点鉴权(见上方"鉴权")。
|
||||
|
||||
与 CLI 一样,服务**默认开启交叉模型否决**(配置默认:on);其 HR-matting 模型随暖机集
|
||||
一起预加载。用 `BGFILTER_CROSS_CHECK=0` 全服务关闭,或用按请求的 `cross_check` 表单
|
||||
字段任意覆盖;`/healthz` 以 `crossCheck` 报告默认值。若配置里 `cross_check.reuse_as_seg:
|
||||
true`(默认关闭),HR-matting 前向会替代主分割前向而非叠加,那个冗余的主分割器会在启动
|
||||
时跳过。
|
||||
|
||||
## 质量检查
|
||||
|
||||
质量检查器在半透明边缘像素上度量 alpha 有效性和边缘溢色。
|
||||
|
||||
```powershell
|
||||
D:\MiniConda\envs\lightML\python.exe -m bgfilter.quality_cli `
|
||||
Outputs\TestImage_rgba.png `
|
||||
--max-edge-green-excess-p95 0.30
|
||||
```
|
||||
|
||||
跑内置样本冒烟检查:
|
||||
|
||||
```powershell
|
||||
D:\MiniConda\envs\lightML\python.exe scripts\smoke_samples.py `
|
||||
--samples-dir Samples `
|
||||
--output-dir Outputs\smoke_samples `
|
||||
--config configs\default.yaml `
|
||||
--device cpu `
|
||||
--fallback-to-chroma-alpha `
|
||||
--max-edge-green-excess-p95 0.30
|
||||
```
|
||||
|
||||
## 备注
|
||||
|
||||
- `Samples/` 和 `Outputs/` 被 Git 忽略。
|
||||
- ViTMatte 和分割权重在首次使用时从 Hugging Face 加载。`anime-seg`
|
||||
(`skytnt/anime-seg`)是普通 ONNX 下载;`birefnet`(`ZhengPeng7/BiRefNet`)自带
|
||||
自定义建模代码,故需 `trust_remote_code=True` 外加 `timm` / `einops` / `kornia`。
|
||||
- 防火墙后下载权重——可靠组合是 `hf-mirror.com` 镜像 **+ 绕过本地代理** **+ 禁用 Xet**:
|
||||
```powershell
|
||||
$env:HF_ENDPOINT = "https://hf-mirror.com" # 国内镜像
|
||||
$env:NO_PROXY = "*" # 绕过代理;镜像是直连
|
||||
$env:HF_HUB_DISABLE_XET = "1" # 这些仓库是 Xet 后端;强制走经典 HTTP
|
||||
```
|
||||
规避两个坑:(1) 镜像 + 海外代理会让镜像的 `resolve` 弹回 `huggingface.co`,新版
|
||||
`huggingface_hub` 会以 `FileMetadataError` 拒绝;(2) 装了 `hf-xet` 时 Xet 下载路径会
|
||||
立即失败。权重缓存好后,用 `HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1` 离线运行
|
||||
(生产环境即如此)。
|
||||
- 把权重打包进项目——不走 HF 缓存,而是把每个模型放进 `models/` 下、以仓库 basename
|
||||
命名的纯文件夹:`models/vitmatte-base-composition-1k`、`models/BiRefNet`、
|
||||
`models/anime-seg`、`models/BiRefNet_HR-matting`(交叉否决第二意见,默认开启)。加载器
|
||||
优先匹配本地文件夹,缺失时回落到 HF 仓库 id / 缓存,故为可选。用例如
|
||||
`hf download ZhengPeng7/BiRefNet --local-dir models/BiRefNet` 填充。用
|
||||
`BGFILTER_WEIGHTS_DIR` 改基目录。`models/` 已被 gitignore。
|
||||
- 前景颜色估计用 pymatting 的 `estimate_foreground_ml`,在 de-spill 前把干净前景色
|
||||
传播进半透明边缘。设 `foreground.method: unmix` 回落到旧的启发式方法。
|
||||
- `docs/green_screen_matting_workflow.md` 是最初的第一阶段绿幕规格;本 README 反映当前
|
||||
的、泛化后的架构。
|
||||
Reference in New Issue
Block a user