一句话
去背景以前意味着把照片传到一台有显卡的服务器上。现在不必了。一个小到可以一次性下载(44 MB)的分割模型可以在浏览器里跑:机器支持 WebGPU 时,一张照片远不到一秒;不支持时,同一个模型在 CPU 上跑 15–25 秒。两种情况下照片都不离开设备。这个模型对背景分明的人物、商品、动物效果好,对发丝叠在发丝上、玻璃,以及任何连摄影师都看不清边缘的东西效果差。
模型是什么
工具用的是 ISNet,来自论文 Highly Accurate Dichotomous Image Segmentation(Qin 等,ECCV 2022)。“Dichotomous”(二分)的意思是任务是二元的:每个像素,是前景还是不是。ISNet 在 DIS5K 数据集上训练——五千张高分辨率图片,配有极其精细的像素级蒙版,对象是自行车、椅子、树这类东西,选它们正因为细枝细杈会打败早先的模型。对 1024 × 1024 的输入,它输出一张 1024 × 1024 的概率图;工具对这张图取阈值、羽化边缘,作为 PNG 的 alpha 通道。
权重以 Apache-2.0 发布。本站自己托管,切成三段以便断点续传,第一次用过之后缓存在浏览器里:第二张照片不再下载任何东西。
“在浏览器里”为什么现在做得到
两样东西得先存在。ONNX Runtime Web 在 JavaScript 里执行训练好的模型,算术运算要么由 WebAssembly 在 CPU 上做,要么——从 2023 年起——由 WebGPU 做,那是把显卡开放给通用计算的浏览器 API。一次分割前向传播是几千亿次乘加,显卡就是为这个造的,单个 CPU 线程不是。
本站工具自己的数字,同样是 1024 像素输入:
| 路径 | 在哪跑 | 每张耗时 |
|---|---|---|
| WebGPU | Chrome / Edge 113+、Safari 26+,带任何现代显卡的笔记本或台式机 | 不到 1 秒 |
| WebAssembly | 任何浏览器,单线程 | 15–25 秒 |
WebAssembly 路径是故意单线程的。多线程 WASM 要求页面处于跨源隔离状态,那个响应头会挡掉所有第三方脚本——包括养活这个站的广告代码。单线程慢,但页面得以免费;活儿被挪进 Web Worker,所以它在磨的时候界面不卡。
内存是另一个约束:运行时加模型加中间激活值需要大约 200 MB 空闲内存。4 GB 内存的手机在 CPU 路径上撑得住;一些更老的手机根本分配不出这块缓冲区,工具会直接说明,而不是让标签页崩掉。
它做不好的,实话实说
- 发丝对着相近的背景。 深色头发对深色墙、金发对米色窗帘。模型看不到边缘,因为像素里根本没有边缘。蒙版要么吃掉头发,要么留一圈墙。
- 透明和反光的东西。 玻璃、水、主体前面的酒杯。分割是二元的;玻璃既不是前景也不是背景,结果是一条硬边穿过它。
- 运动模糊。 模糊的边缘没有唯一正确的分界线。
- 多个主体。 模型保留它认为是“主体”的一切;两个人通常都留,一个人和一条大狗可能只留一个。
- 很小的主体。 输入长边 1024 px;一张远景里 60 px 高的人,变成蒙版里的几十个像素,出来是一团。
干净的商品图、素墙前的人像、地板上的宠物、纸上的 logo,它很可靠——训练集里装满的就是这些。
拿到结果之后
输出是带真实透明通道的 PNG。这是放进幻灯片、商品页或另一张照片的正确格式,也是发邮件的错误格式——1200 万像素的 PNG 抠图有 20–30 MB。目的地要小文件又不需要透明,就转成白底 JPEG;需要透明又要更小,带 alpha 的 WebP 是 PNG 的三分之一。压缩两种都能处理。