feat: initial project setup
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
# BiRefNet WebUI
|
||||
|
||||
**自包含**的网页版智能抠图工具:模型代码、权重、Python 运行时全部在项目目录内,
|
||||
不依赖 ComfyUI,整个文件夹拷到别的机器(有 NVIDIA 显卡)也能直接跑。
|
||||
|
||||
浏览器里拖图 → 一键抠图 → 对比 → 下载;也可以直接填两个目录,整目录批量抠图。
|
||||
|
||||
- **零 Web 框架依赖**:标准库 `http.server` 实现,不装 Gradio / FastAPI / Flask
|
||||
- **自带运行时**:`python/` 内置 Python 3.12 + torch(CUDA),无需配置环境
|
||||
- **GPU 串行队列**:同一时刻只跑一个模型,8G 显存也能稳定使用
|
||||
- **目录批量**:给一个图片目录 + 一个输出目录,结果按 `RMBG_原名_时间戳.后缀` 落盘
|
||||
- 数值行为与 ComfyUI 节点 `comfyui_birefnet_ll` 对齐:同款预处理、`fast-foreground-estimation` 前景精修
|
||||
|
||||
## 快速开始
|
||||
|
||||
```
|
||||
方式一:双击 run.bat
|
||||
方式二:python\python.exe Webui.py
|
||||
```
|
||||
|
||||
启动后自动打开 `http://127.0.0.1:7861/`。
|
||||
|
||||
> 把整个项目文件夹移动或拷贝到其它路径/机器后仍可直接运行;
|
||||
> 若目标机器没有 NVIDIA 显卡,会自动退回 CPU(较慢)。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
BiRefNet_WebUI/
|
||||
├─ Webui.py 启动入口
|
||||
├─ run.bat 双击启动(优先用自带 python\ 运行时)
|
||||
├─ selftest.py 端到端自检(python\python.exe selftest.py)
|
||||
├─ selftest_batch.py 批量抠图自检(纯逻辑 + 假引擎流水线 + HTTP 契约,秒级)
|
||||
├─ python/ ★ 自带 Python 3.12 运行时(torch 2.13 + CUDA)
|
||||
├─ models/ ★ BiRefNet 权重(birefnet / Portrait)
|
||||
├─ vendor/comfyui_birefnet_ll/ ★ 模型代码(来自 ComfyUI 节点,含 LICENSE)
|
||||
├─ birefnet_web/ 服务端
|
||||
│ ├─ compat.py 模型代码定位与 folder_paths 垫片
|
||||
│ ├─ fsutil.py 图片后缀集合、文件名清洗(不依赖 torch)
|
||||
│ ├─ imageops.py 预处理 / 后处理
|
||||
│ ├─ batch.py 批量:路径校验、目录扫描、输出命名
|
||||
│ ├─ engine.py 模型扫描、加载缓存与推理
|
||||
│ └─ server.py HTTP 服务、REST API、任务队列
|
||||
├─ web/ 前端(原生 HTML/CSS/JS,无构建步骤)
|
||||
│ ├─ zip.js 纯 JS 的 ZIP 打包器(跨任务打包结果用)
|
||||
│ └─ test_app.js 前端回归测试(node web/test_app.js,无需浏览器)
|
||||
├─ outputs/ 结果输出(按任务分目录)
|
||||
└─ config.json 首次启动自动生成
|
||||
```
|
||||
|
||||
★ = 随项目分发的核心资源。
|
||||
|
||||
## 使用
|
||||
|
||||
1. **左侧「图片」**:拖入 / 点击选择 / `Ctrl+V` 粘贴。**一次只放一张**:新图会替换上一张,
|
||||
重复拖入同一张会被去重提示;一次拖入多张时只保留最后一张
|
||||
2. **「模型」**:选择权重(默认扫描项目 `models/`,也可加别的目录)
|
||||
3. **「参数」**:按需调整(都有与节点一致的默认值)
|
||||
4. 点击 **开始抠图**,右侧实时显示进度;**新任务的结果追加到列表末尾,
|
||||
已有记录不会被清空**(换参数、传新图、重新处理都不影响)
|
||||
5. 结果卡片上**左右拖动**分割线对比原图与结果,支持 抠图/遮罩/原图 三种视图、单图下载、ZIP 打包
|
||||
6. **结果列表交互**:
|
||||
- 每条记录的文件名下方有一行**参数摘要**(该次处理使用的模型/尺寸/背景等,
|
||||
完整参数在悬停提示里),跨任务累积成历史
|
||||
- **点击文件名或「重新处理」** → 把该记录的原图放回待处理槽,**并把它当时使用的
|
||||
参数重新赋值到左侧面板**,可直接重跑(同一记录重复点击会去重)
|
||||
- **参数记忆**:每张图最近一次使用的参数按文件名自动保存(localStorage),
|
||||
之后再把同名图片拖进来时自动套用;同一张图多次处理时总是记录最新的参数
|
||||
- **点击卡片本体** → 选中该记录(主题色描边),再点一次取消,`Esc` 也可取消
|
||||
- **点卡片右上角 ×** → 从结果列表移除该条记录(仅移除列表项,`outputs/` 下的文件保留)
|
||||
- **打包下载 ZIP** 覆盖列表里的全部记录(可能来自多个任务,同名自动加序号)
|
||||
- 刷新页面后,服务端还在内存里的任务历史会自动恢复显示(含参数)
|
||||
|
||||
> 需要按目录整批处理时,用左侧面板 **4 · 批量处理**,详见下一节。
|
||||
|
||||
## 批量处理(整目录抠图)
|
||||
|
||||
不想一张张拖图时,用左侧面板 **4 · 批量处理**:
|
||||
|
||||
1. **图片目录(模板路径)**:待处理图片所在目录,例 `F:\photos\待抠图`
|
||||
2. **输出目录**:结果写到哪;**留空=项目 `outputs/` 目录**(输入框默认已填好绝对路径)
|
||||
3. 勾选 **包含子目录** 则递归扫描子目录
|
||||
4. 点 **开始批量抠图** → 结果区顶部出现逐文件清单:`源文件名 → 输出文件名 → 状态 / 耗时`
|
||||
|
||||
抠图参数(模型、尺寸、背景、精修…)**沿用左侧「模型 / 参数」面板当前设置**,与单图模式完全一致。
|
||||
|
||||
### 目录与落盘规则
|
||||
|
||||
| 行为 | 说明 |
|
||||
| --- | --- |
|
||||
| 路径必须已存在 | 输入目录、输出目录都必须真实存在;**本工具不会创建任何目录**,路径不对直接在界面上报错 |
|
||||
| 默认输出目录 | 项目内 `outputs/`(前端按服务端返回的绝对路径预填) |
|
||||
| 命名规则 | `RMBG_<原文件名主干>_<Unix 时间戳>.<后缀>`;主干超过 **20 字符**按字符截断(中文同样按字符算) |
|
||||
| 后缀 | 默认沿用原后缀;但透明输出需要 alpha 通道,遇到 `jpg/jpeg/bmp` 会退化成 `.png`(否则会被压成白底) |
|
||||
| 遮罩文件 | 默认**不产出**;勾选「同时输出遮罩」后才额外写一份 `<主结果同名>_mask.png`(灰度,白=前景) |
|
||||
| 重名不覆盖 | 同一秒内的同名结果自动加 `_1`、`_2` … 递增避让 |
|
||||
| 扫描范围 | 只认图片后缀;**跳过 `RMBG_` 开头的文件**(避免把上次产物又抠一遍);输出目录在输入目录内时会被排除 |
|
||||
| 输入 = 输出 | 允许:结果与源图同目录,靠 `RMBG_` 前缀区分 |
|
||||
| 原图 | 批量模式**不拷贝、不修改**源图,就地读取 |
|
||||
| 结果展示 | 批量结果不铺成单图卡片(几百张会拖慢页面),只在结果区顶部列清单;文件本体已在输出目录,无需再下载 |
|
||||
|
||||
> 批量任务与单图任务共用同一个串行队列(同一时刻只跑一张),不会抢显存;关掉页面不影响服务端继续跑完。
|
||||
|
||||
## 参数说明
|
||||
|
||||
「模型 / 设备」与「参数」两个面板中每一项的含义(均有与 ComfyUI 节点一致的默认值,改了会记入参数摘要):
|
||||
|
||||
### 设备与精度
|
||||
|
||||
| 参数 | 说明 | 默认 |
|
||||
| -- | ------------------------------------------------------------------------ | ---- |
|
||||
| 设备 | 自动(GPU)/ CPU | auto |
|
||||
| 精度 | auto = fp32 权重 + fp16 autocast(官方推荐做法);float16 最省显存;出现 NaN 会自动回退 fp32 重算 | auto |
|
||||
| 架构 | v1(新版 safetensors)/ old(旧版 .pth)/ 自动识别 | auto |
|
||||
|
||||
### 预处理尺寸(送入模型前的缩放方式)
|
||||
|
||||
BiRefNet 推理前会把原图缩放到固定输入尺寸,这一项决定怎么缩:
|
||||
|
||||
| 模式 | 说明 |
|
||||
| -------------------- | ------------------------------------ |
|
||||
| 固定 1024×1024(square) | 官方推荐做法:不论原图比例,直接拉伸到 1024×1024,精度最稳定 |
|
||||
| 长边自适应(longest) | 保持宽高比,把长边缩放到指定值(边长对齐 32 的倍数),另一边按比例算 |
|
||||
| 自定义宽高(custom) | 手动指定「宽 / 高」两个输入框(默认各 1024),不保持原图比例 |
|
||||
|
||||
> 输入尺寸越小推理越快、越省显存(如 512);越大细节越丰富但更慢。
|
||||
|
||||
### 其余参数
|
||||
|
||||
| 参数 | 说明 | 默认 |
|
||||
| ------- | ------------------------------------------------------------------------------------- | -------- |
|
||||
| 插值方式 | 预处理缩图与遮罩还原回原尺寸时使用的插值算法(bilinear / nearest / bicubic 等) | bilinear |
|
||||
| 遮罩阈值 | 大于 0 时,把低于该阈值的 alpha 概率直接置零(不做二值化,只清零弱值),可清理弱边缘杂讯;0 = 不处理 | 0 |
|
||||
| 背景 | 抠图结果的合成方式:**透明(PNG Alpha)** 输出带 alpha 通道的 PNG;**纯色** 则把前景合成到指定颜色上(含绿幕、色板快选) | 透明 |
|
||||
| 前景精修 | fast-foreground-estimation:按遮罩估计前景色,去除半透明边缘残留的原背景色(白底抠图边缘发白就是它治的)。超大图(超过像素上限)会自动跳过并提示 | 开 |
|
||||
| — 大核 r1 | 精修第一轮 box blur 的核尺寸,用于估计整体前景色 | 90 |
|
||||
| — 小核 r2 | 精修第二轮 box blur 的核尺寸,用于收细边缘 | 6 |
|
||||
| 同时输出遮罩 | 额外输出一张 8bit 灰度 PNG(黑白遮罩,白色 = 前景),可用于后期合成。**默认关闭**,需要时才勾 | 关 |
|
||||
| 最终尺寸 · 最长边 | 按原图比例等比缩放结果,使**最长边等于**该值;0 = 保持原图尺寸。例:2000×3000 填 1440 → 960×1440;3000×2000 填 1440 → 1440×960 | 0 |
|
||||
|
||||
> 「最终尺寸 · 最长边」精确定义:设原图(抠图结果原尺寸)为 `W×H`,填充值为 `L`
|
||||
>
|
||||
> - `L = 0`:不缩放,原样输出(默认)
|
||||
> - `L > 0`:`k = L / max(W, H)`,输出 `round(W·k) × round(H·k)`,最长边恰好等于 `L`;短边按比例取整,可能与理论值差 1 像素
|
||||
> - 原图最长边**小于** `L` 时会**放大**(这点与旧的「输出长边上限」不同,旧参数只缩不放,已被本参数取代)
|
||||
> - 缩放同时作用于抠图结果与(勾选时的)遮罩文件,两者始终保持同尺寸
|
||||
|
||||
## 命令行参数
|
||||
|
||||
```
|
||||
python\python.exe Webui.py [--host 0.0.0.0] [--port 7861] [--device auto|cpu|cuda]
|
||||
[--dtype auto|float32|float16|bfloat16]
|
||||
[--model-dir 路径]... 追加模型目录
|
||||
[--node-dir 路径] 指定模型代码目录(默认用项目内 vendor/)
|
||||
[--output-dir 路径] 结果输出目录(默认 ./outputs)
|
||||
[--max-cached-models N] 显存中驻留的模型数(默认 1)
|
||||
[--no-browser] [--save-config] [--check]
|
||||
```
|
||||
|
||||
`--check` 只做环境自检(依赖、GPU、模型扫描)后退出,适合排障。
|
||||
|
||||
## 模型代码与权重
|
||||
|
||||
模型代码内联在 `vendor/comfyui_birefnet_ll/`(来源:ComfyUI 节点 comfyui_birefnet_ll,
|
||||
遵循其 LICENSE)。`birefnet_web/compat.py` 会在 import 阶段注入一个最小 `folder_paths`
|
||||
垫片(模型包只在「加载骨干预训练权重」时用到它,本工具始终以 `bb_pretrained=False`
|
||||
构建,因此垫片返回 None 即可),从而脱离 ComfyUI 独立运行。
|
||||
|
||||
权重文件(放入 `models/` 即可,扫描时自动识别):
|
||||
|
||||
- 新版 `*.safetensors`:[ZhengPeng7 的 HuggingFace 仓库](https://huggingface.co/ZhengPeng7),如 `General.safetensors`、`Portrait.safetensors`
|
||||
- 旧版 `BiRefNet-DIS_ep580.pth` / `BiRefNet-ep480.pth`
|
||||
- 骨干权重(`swin_*` / `pvt_*`)会被自动忽略,不会被当成抠图模型
|
||||
|
||||
也可用 `--model-dir` 或 `config.json` 的 `model_dirs` 追加其它目录
|
||||
(例如继续共用 ComfyUI 的 `models/BiRefNet`,两处权重会合并去重显示)。
|
||||
|
||||
## HTTP API
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
| ---- | ----------------------------------------- | ----------------------------------------------- |
|
||||
| GET | `/api/state` | 环境、模型列表、默认参数 |
|
||||
| GET | `/api/models` · POST `/api/models/reload` | 模型列表 / 重新扫描 |
|
||||
| POST | `/api/tasks` | multipart 提交:`files`(可多份)+ `options`(JSON,字段同上) |
|
||||
| POST | `/api/batch` | JSON 提交目录批量:`input_dir` / `output_dir`(可空=项目 outputs)/ `recursive` / `options`;两个目录都必须已存在 |
|
||||
| GET | `/api/tasks` | 任务历史列表(含各自参数与 `mode`,前端据此恢复结果历史) |
|
||||
| GET | `/api/tasks/<id>` | 任务状态与进度(前端 400ms 轮询);`?tail=N` 只回传最后 N 张,批量任务靠它压载荷 |
|
||||
| POST | `/api/tasks/<id>/cancel` | 取消(阶段粒度) |
|
||||
| GET | `/api/tasks/<id>/file/<index>/<kind>` | 取结果,kind = cutout / mask / original |
|
||||
| GET | `/api/tasks/<id>/zip?kind=cutout` | 打包下载 |
|
||||
| POST | `/api/engine/unload` | 释放显存 |
|
||||
| POST | `/api/shutdown` | 关闭服务 |
|
||||
|
||||
## 常见问题
|
||||
|
||||
- **双击 run.bat 一闪而过**:确认 `run.bat` 是 CRLF 换行(纯 LF 的批处理会被 cmd 静默终止)
|
||||
- **显存不足(OOM)**:精度选 `float16`,或预处理尺寸改小(如 512);默认同时只驻留 1 个模型
|
||||
- **没有可用模型**:确认 `*.safetensors` 在 `models/` 下,或用 `--model-dir` 指定
|
||||
- **结果边缘有原背景色残留**:确认「前景精修」开启
|
||||
- **批量时报「输出目录不存在」**:本工具不会自动建目录,请先在资源管理器里把输出目录建好再填
|
||||
- **批量产物多出 `_mask.png`**:说明勾了「同时输出遮罩」(默认不勾);取消勾选即可只留抠图结果
|
||||
- **输出尺寸不对**:检查「最终尺寸 · 最长边」——填了非 0 值就会把结果等比缩放到该最长边(小图会被放大),想原样输出请填 0
|
||||
- **旧版本里设过「输出长边上限」**:该参数已改名为「最终尺寸 · 最长边」,旧值会自动带到新输入框;浏览器里存的老参数还会自动修正一次「同时输出遮罩」的默认值
|
||||
- **批量结果名被截断**:设计如此——原文件名主干超过 20 字符会截断,避免超长文件名;时间戳用来区分多次处理
|
||||
- **CPU 很慢**:正常现象,建议 512 分辨率 + float32
|
||||
- **想换 Python**:设环境变量 `BIREFNET_PYTHON=<解释器路径>`(需已装 `requirements.txt` 依赖);
|
||||
缺依赖时入口会自动切换到自带的 `python\` 运行时
|
||||
|
||||
## 环境要求
|
||||
|
||||
自带运行时已就绪,无需安装。若用自己的解释器:Python 3.9+,
|
||||
`pip install -r requirements.txt`(torch / torchvision / numpy / pillow / safetensors /
|
||||
timm / einops / kornia / huggingface_hub / tqdm,可选 opencv-python)。
|
||||
Reference in New Issue
Block a user