去除背景(透明视频)
背景去除——在 VFX 中也称为抠像——将前景主体(通常是人)与其背景分离。输出是一个带有 alpha 通道的视频:背景区域完全透明,主体区域不透明。将其作为 <video> 标签放入任何 HyperFrames 合成中,主体就会浮在你放在其后的任何内容之上。
CLI 提供内置的 remove-background 命令,在本地运行——无需 API 密钥、无需云上传、无需绿幕。
快速开始
验证 ffmpeg 已安装
流水线需要 ffmpeg 和 ffprobe 进行解码 + 编码。大多数系统已安装;如果没有:
# macOS
brew install ffmpeg
# Ubuntu / Debian
sudo apt install ffmpeg
用 npx hyperframes doctor 确认——两者都应显示为绿色。
去除视频背景
npx hyperframes remove-background subject.mp4 -o transparent.webm
首次运行时,CLI 下载约 168 MB 模型权重到 ~/.cache/hyperframes/background-removal/models/。后续运行重用缓存。
输出:
◇ Removed background from 240 frames in 38.4s (6.3 fps, CoreML) → ./transparent.webm
将其放入合成中
输出是标准的 VP9 带 alpha 的 WebM。Chrome 的 <video> 元素原生解码 alpha 平面——无需特殊播放器:
<div class="scene">
<!-- background layer -->
<img src="city.jpg" class="bg" />
<!-- transparent subject floats on top -->
<video src="transparent.webm" autoplay muted loop playsinline></video>
</div>
使用常规 hyperframes render 渲染合成。
工作原理
流水线运行四个阶段,全部在本地:
ffmpeg decode → u²-net_human_seg inference → alpha composite → ffmpeg encode
(raw RGB) (320×320 mask, then upsampled) (VP9-alpha)
模型是 u²-net_human_seg(MIT 许可证,约 168 MB ONNX)。它通过 onnxruntime-node 使用机器上最佳可用执行提供程序运行:Apple Silicon 上的 CoreML、NVIDIA 上的 CUDA,否则使用 CPU。
输出使用 Chrome 的 <video> 元素解码 alpha 所需的确切 ffmpeg 标志进行编码——-pix_fmt yuva420p 加上 alpha_mode=1 元数据标签。如果这些设置错误,浏览器会静默丢弃 alpha 平面。
输出格式
| 扩展名 | 编解码器 | 使用场景 | 大小(4 秒 @ 1080p) |
|---|---|---|---|
.webm(默认) | VP9 带 alpha | 放入 <video> 实现 HTML5 原生透明播放 | 约 1 MB |
.mov | ProRes 4444 带 alpha | 在 Premiere / Resolve / Final Cut 中编辑往返 | 约 50 MB |
.png | PNG 带 alpha | 单图抠像(仅当输入也是单张图片时) | 不定 |
npx hyperframes remove-background subject.mp4 -o transparent.webm # web playback
npx hyperframes remove-background subject.mp4 -o transparent.mov # editing
npx hyperframes remove-background portrait.jpg -o cutout.png # still image
图层分离:同时输出抠像和背景板
传递 --background-output(别名 -b)可在抠像旁边写入第二个透明视频。相同的源 RGB,alpha 是反向遮罩——周围环境区域不透明,主体区域透明。结果是在一次推理中实现干净的两层分离:
npx hyperframes remove-background subject.mp4 \
-o subject.webm \
--background-output plate.webm
| 输出 | Alpha | 用途 |
|---|---|---|
subject.webm | 遮罩——主体不透明 | 前景层(层栈顶部) |
plate.webm | 255 − mask——主体区域透明 | 背景层;将你想要放在主体轮廓下方的任何内容放在此层和 subject.webm 之间 |
两个编码器共享源的宽度/高度/帧率和你的 --quality 预设,因此层是像素对齐的。编码开销大约翻倍;分割开销不变。
💡 Tip
这是一个挖孔板,而非修复填充的干净板。
plate.webm中的主体区域完全透明——你需要在其下方合成不透明内容(图形、模糊副本、不同场景)来填充孔洞。如果你需要主体位置的真实填充背景,请使用视频修复工具(LaMa、ProPainter、RunwayML Inpaint)——remove-background不适合此用途。
挖孔板 vs. 干净板——差异何时重要?
挖孔板保留原始环境并使主体区域透明。干净板用重建的背景填充主体区域——由单独的修复模型生成。单独在黑色背景上显示每个:
| 挖孔板(此命令) | 干净板(修复填充) | |
|---|---|---|
| 主体区域 | 透明轮廓 | 重建的背景像素 |
| 单独查看时 | 人形孔洞 | 空房间 |
| 开销 | 一次推理,一次额外 ffmpeg 编码 | 第二个模型(LaMa、ProPainter、E2FGVI) |
| 工具 | remove-background --background-output | 此 CLI 之外 |
判断标准是:是否有东西需要从主体原来的位置透过轮廓显示?
| 用例 | 你需要什么 |
|---|---|
| 文本/图形位于抠像和板之间(如上例) | 挖孔板——图形填充孔洞。 |
| 将主体合成到无关场景上 | 都不需要。只需使用 subject.webm;板无关紧要。 |
| 显示"没有人的房间"作为真实背景 | 干净板——挖孔板会显示透明空洞。 |
| 用不同主体替换人物(重新定向) | 干净板——新主体需要其下方的真实像素。 |
| VFX 抠像/"从这个镜头中移除一个群演" | 干净板——经典的修复用例。 |
如果有不透明物始终覆盖轮廓,挖孔板就足够了,而且比运行修复工具便宜约 1000 倍。
两层合成模式
两层模式在功能上是 text-behind-subject 的直接替代,无需项目中存在原始 presenter.mp4——板作为底层替代了它:
<!-- z=1 inverse-alpha plate fills everything except the subject's silhouette -->
<video src="plate.webm" data-start="0" data-duration="6" data-track-index="0" muted playsinline></video>
<!-- z=2 anything you want occluded by the subject lives here -->
<h1 style="z-index:2; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);">
MAKE IT IN HYPERFRAMES
</h1>
<!-- z=3 the cutout puts the subject back on top -->
<div class="cutout-wrap" style="position:absolute;inset:0;z-index:3">
<video src="subject.webm" data-start="0" data-duration="6" data-track-index="1" muted playsinline></video>
</div>
约束:此标志需要视频输入,两个输出都使用 .webm 或 .mov。不适用于图片输入(无时间配对可做),也不接受 .png 作为板。
性能
来自抠像评估的真实数据,在 4 秒 1080p 片段上运行 u²-net_human_seg:
| 平台 | 提供程序 | 毫秒/帧 | 30 秒片段 |
|---|---|---|---|
| Apple Silicon(M2 Pro / M3 / M4) | CoreML | ~263 | ~2 分钟 |
| NVIDIA GPU(T4、A10、RTX) | CUDA | ~80–150 | ~30–60 秒 |
| Linux x86 | CPU | ~1100 | ~16 分钟 |
| macOS Intel | CPU | ~900 | ~13 分钟 |
抠像是离线预处理——你对每个素材运行一次并重用输出。仅 CPU 较慢但始终有效;如果你重复使用同一主体片段,在更快的机器上运行一次并将透明输出提交到你的项目中。
明确选择设备
--device auto 是默认值,适合几乎所有人。此标志存在是为了两种情况:
- 在 GPU 机器上强制使用 CPU,当你想让 GPU 空闲用于其他工作,或正在调试特定提供程序的问题:
npx hyperframes remove-background subject.mp4 -o transparent.webm --device cpu
- 选择 CUDA,通过设置
HYPERFRAMES_CUDA=1并提供支持 GPU 的onnxruntime-node构建(捆绑的构建仅支持 CPU + CoreML,以保持 99% 无 GPU 用户的安装包体积小):
HYPERFRAMES_CUDA=1 npx hyperframes remove-background subject.mp4 -o transparent.webm --device cuda
运行 npx hyperframes remove-background --info 查看你机器上检测到的提供程序以及 auto 会选择哪个。
在合成中使用透明视频
透明 WebM 的行为与任何其他视频元素相同。你最常用的两种模式:
主体在背景图片上:
<div style="position: relative; width: 1920px; height: 1080px;">
<img src="background.jpg" style="position: absolute; inset: 0;" />
<video
src="transparent.webm"
autoplay
muted
loop
playsinline
style="position: absolute; right: 80px; bottom: 0; height: 90%;"
></video>
</div>
主体在 HyperFrames 场景上:
<!-- scene contents (text, animations, etc.) -->
<div class="title-card">Welcome</div>
<!-- subject layered on top -->
<video src="transparent.webm" autoplay muted loop playsinline class="subject"></video>
抠像继承合成的帧率和时间轴——它在场景持续时间内播放一次,因此尽可能将源片段长度与场景长度匹配。如果场景比片段长,loop 会处理。
💡 Tip
渲染包含
<video>元素的合成时,渲染器内部通过 ffmpeg 读取源。透明 WebM 解码时保留 alpha 平面。
合成模式与陷阱
抠像 webm 是源 mp4 RGB 的重新编码副本——抠像流水线将源解码为原始 RGB,运行分割,然后重新编码为带 alpha 的 VP9。这个选择取决于你将其放在什么后面。
三种模式
| 模式 | 抠像后面 | 结果 |
|---|---|---|
| 抠像在不同场景上 (最常见) | 静态图片、渐变、动画背景或无关素材 | 干净。抠像是主体的唯一来源——无重复、无边缘光晕。使用任何 --quality。 |
| 抠像在自身源 mp4 上 (text-behind-subject、带覆盖层的头像) | 生成抠像的同一 mp4 | 同一个人的两个 RGB 来源。在默认 --quality balanced(crf 18)下重复几乎不可见;在 --quality fast(crf 30)下轮廓会出现轻微色偏/柔边。重要镜头使用 --quality best(crf 12)。 |
| 抠像在不同素材的同一主体上 | 同一人的另一个镜头 | 看起来像两个重叠的人。避免——重新拍摄或重新剪辑源。 |
Text-behind-subject:推荐布局
将标题放在主持人_后面_,使其轮廓遮挡文本:
<!-- z=1 base mp4: full lobby + presenter, plays the whole scene -->
<video
id="cf-base"
data-start="0" data-duration="6" data-media-start="0" data-track-index="0"
src="presenter.mp4"
muted playsinline
></video>
<!-- z=2 headline -->
<h1 id="cf-headline" style="position:absolute;top:50%;left:50%;
ransform:translate(-50%,-50%); z-index:2;
color:#fff; text-shadow:0 6px 32px rgba(0,0,0,.55);
clip-path:inset(0 0 100% 0); font-size:220px; font-weight:900;">
MAKE IT IN HYPERFRAMES
</h1>
<!-- z=3 cutout: same source, alpha around presenter, hidden until the cut.
The wrapper carries the opacity, NOT the <video> itself. -->
<div class="cutout-wrap" style="position:absolute;inset:0;z-index:3;opacity:0">
<video
id="cf-cutout"
data-start="0" data-duration="6" data-media-start="0" data-track-index="1"
src="presenter.webm"
muted playsinline
></video>
</div>
const tl = gsap.timeline({ paused: true });
const CUT = 3.3;
// Reveal the headline early
l.to("#cf-headline", { clipPath: "inset(0 0 0% 0)", duration: 0.6, ease: "expo.out" }, 0.25);
// At the cut, flip the cutout wrapper visible — silhouette punches through the headline
l.set(".cutout-wrap", { opacity: 1 }, CUT);
// Sentinel: extend timeline to the composition's full duration so the renderer
// doesn't bail past the last meaningful tween.
l.set({}, {}, 6);
两个不明显的规则
1. 将抠像视频包装在非定时 <div> 中,动画包装器而非视频。
框架对任何带有 data-start/data-duration 的元素在其"活跃"时强制 opacity: 1——这是它控制片段可见性的方式。视频元素上的 CSS opacity: 0 会被框架的片段生命周期静默覆盖,因此对视频元素的 opacity 补间不会起作用。将视频包装在一个没有 data-* 属性的 <div> 中;包装器完全由你的 CSS/GSAP 控制。
2. 两个视频都从 data-start="0" 开始并在 t=0 同步解码。
"延迟挂载"抠像(data-start="3.3" 以匹配切割点)很诱人。不要这样做——Chrome 在挂载时执行 seek + 解码器预热,这可能在切割时刻使一帧偏离基础 mp4。两个视频都从 t=0 挂载并动画化抠像包装器的 opacity,两个解码器以相同方式推进并保持帧精确。
质量预设与颜色匹配
当抠像叠加在其自身源 mp4 上时,编码器的 CRF 直接影响边缘处重复的可见程度:
--quality | CRF | 文件大小(12 秒 @ 1080p) | 使用场景 |
|---|---|---|---|
fast | 30 | 约 2 MB | 抠像在无关背景上且文件大小重要 |
balanced (默认) | 18 | 约 6 MB | 推荐用于 text-behind-subject 和任何叠加在源上的模式 |
best | 12 | 约 12 MB | 重要镜头、母版或任何你将在下游重新编码的内容 |
编码器还写入 BT.709 + limited-range 颜色元数据,使 Chrome 的 YUV→RGB 管线与源 mp4 匹配。没有这些标签,即使在无损质量下,抠像的渲染也会与底层 mp4 略有不同(可见的红色/肤色偏移)。
u²-net_human_seg 擅长和不擅长的场景
该模型专为人像/人物抠像而构建。它在以下情况表现出色:
- ✅ 主体是人,头肩像或全身
- ✅ 构图相当稳定(不是广角手持拍摄)
- ✅ 背景与主体有对比
它在以下情况会困难或失败:
- ❌ 非人类主体(产品、动物、物体)。模型会返回大部分为空的遮罩。
- ❌ 复杂背景上的非常精细的头发细节。320×320 的推理分辨率意味着发尖会被柔化——大多数用例没问题,但合成师会注意到。
- ❌ 帧间时间一致性。每帧独立处理,因此静态背景上移动的主体可能显示细微的边缘闪烁。对于大多数网页播放这不可见;对于高端 VFX 可能很重要。
- ❌ 直播或实时捕获。流水线仅支持批处理。
如果你的用例遇到以下情况之一,请参见下面的替代方案。
替代方案——当内置命令不是合适的工具时
CLI 有意只提供一个模型——MIT 许可、到处运行、为人物/人像视频提供生产质量输出的模型。以下列表优先列出与 HyperFrames 自然搭配的免费开源工具。每个条目都标注了实际的注意事项——许可证、安装成本、硬件需求——以便你根据情况选择正确的工具。完整基准测试在抠像评估中。
免费开源 CLI 和库
这些都在本地运行,无需账户、无需上传、无水印。
| 工具 | 使用场景 | 注意事项 |
|---|---|---|
rembg(Python,MIT) | 你需要不同的主体类型——isnet-general-use 用于物体/动物/产品,birefnet-portrait 用于头发质量上限,silueta 用于极小的约 40 MB 体积。与我们默认模型同族,更多选择。 | 需要 Python + pip install rembg。部分捆绑模型(birefnet-*)需要约 4 GB RAM 且仅支持 CPU |
| BiRefNet(PyTorch,MIT) | 可用的最高保真度人像抠像——头发边缘明显优于 u²-net | 较重(约 4 GB 推理 RAM),CPU 上较慢,在评估时 Apple CoreML 上有问题 |
| Robust Video Matting (RVM)(PyTorch,GPL-3.0) | 唯一内置时间一致性的广泛可用模型——移动主体无边缘闪烁。当你抠像长视频头像且帧间稳定性重要时的最佳选择 | GPL-3.0 许可证与大多数商业/专有代码库不兼容。使用前请查看你仓库的许可证 |
| Backgroundremover(Python,MIT) | u²-net 的简单 pip install 包装器;如果你想要 Python API 而非我们的 Node CLI 会很方便 | 与我们同模型族,无质量差异——选择适合你技术栈的 |
| ComfyUI(开源,GPL-3.0 核心) | 自定义工作流:链接分割模型 + alpha 精炼 + 时间平滑。适用于棘手情况(多个主体、头发与相似背景、运动素材)的正确工具 | 设置较复杂(Python、模型、节点图)。对于重复的专业工作值得 |
在外部运行其中任何一个后,使用以下命令将输出编码为 HyperFrames 兼容的透明 WebM:
ffmpeg -i frames-%04d.png -c:v libvpx-vp9 \
-pix_fmt yuva420p \
-metadata:s:v:0 alpha_mode=1 \
-auto-alt-ref 0 -b:v 0 -crf 30 \
ransparent.webm
免费桌面 / GUI 工具
| 工具 | 使用场景 | 注意事项 |
|---|---|---|
| DaVinci Resolve — Magic Mask | 你已经在 Resolve 中编辑,想要基于画笔的 UI 并手动精炼,且需要将 alpha 往返到更大的编辑中 | macOS / Windows / Linux 桌面安装。免费版涵盖 Magic Mask;付费 Studio 版本在某些功能上解锁更高分辨率 |
| Backgroundremover.app(web) | 一次性图片抠像,无需注册,无水印 | 仅限单张图片,不是视频。免费层是托管的但底层工具是相同的 rembg 模型族 |
| PhotoRoom Background Remover(web) | 快速一次性图片,精美 UI,无需注册 | 仅限单张图片,电商优化模型 |
Web SaaS 工具(免费层,有限制)
| 工具 | 使用场景 | 注意事项 |
|---|---|---|
| unscreen.com | 快速一次性视频,无需安装,拖放操作 | 免费层有水印且限于短片段(约 10 秒预览)。付费移除两者。由 remove.bg 团队运营 |
| RunwayML — Green Screen | 精美 UI,带画笔精炼和时间感知跟踪;SaaS 中最接近专业抠像的 | 有免费层但有积分限制;认真使用需要订阅 |
| Kapwing — Background Remover | 基于浏览器,与其视频编辑器集成 | 免费层有水印;付费移除 |
如何选择
- 人物/人像视频,网页播放,MIT 干净→使用内置
hyperframes remove-background(这就是它调优的用途)。 - 非人类主体(产品、动物、物体)→
rembg配合isnet-general-use。 - 最高人像质量,尤其是头发→通过 Python 使用
BiRefNet。 - 边缘闪烁会可见的长视频,GPL 可以→
RVM。 - 一次性营销片段,无需安装→DaVinci Resolve(免费)用于视频,Backgroundremover.app 用于静态图片。
- 现成模型无法处理的特殊案例→ComfyUI 配合自定义图。
故障排除
模型下载失败或挂起
权重存储在 GitHub Releases 上(rembg 的 v0.0.0 发布,约 168 MB)。如果你的网络阻止 GitHub 或下载中断:
# Manually download and drop into the cache
mkdir -p ~/.cache/hyperframes/background-removal/models
curl -L -o ~/.cache/hyperframes/background-removal/models/u2net_human_seg.onnx \
https://github.com/danielgatis/rembg/releases/download/v0.0.0/u2net_human_seg.onnx
后续 remove-background 运行将跳过下载并使用你的本地副本。
"ffmpeg and ffprobe are required"
流水线调用 ffmpeg 进行解码 + 编码。在 macOS 上通过 brew install ffmpeg 安装,在 Debian/Ubuntu 上通过 sudo apt install ffmpeg 安装。使用 npx hyperframes doctor 验证。
输出 WebM 在浏览器中看起来完全不透明
Chrome 仅在 WebM 编码为 yuva420p 且带有 alpha_mode=1 元数据标签时才读取 alpha 平面。CLI 设置了这两个。如果你自己重新编码输出(例如使用另一个 ffmpeg 调用),保留这些标志:
ffmpeg -i in.webm -c:v libvpx-vp9 \
-pix_fmt yuva420p \
-metadata:s:v:0 alpha_mode=1 \
-auto-alt-ref 0 \
out.webm
要验证 WebM 是否有 alpha,提取第一帧并检查:
ffmpeg -y -c:v libvpx-vp9 -i out.webm -frames:v 1 -pix_fmt rgba -update 1 frame0.png
解码后的 frame0.png 应该是 RGBA 并具有非零 alpha 值。
CoreML "可用"但推理未能启动
如果 CoreML 绑定失败,流水线会自动回退到 CPU,并显示警告。如果你想完全跳过 CoreML 尝试,强制使用 CPU:
npx hyperframes remove-background subject.mp4 -o transparent.webm --device cpu
Alpha 遮罩边缘粗糙或锯齿状
这通常意味着源帧在相似色调的背景上有高对比度,模型的 320×320 推理分辨率显露出来。两条前进路径:
- 重新构图或重新拍摄,为主体提供更具对比度的背景。
- 通过
rembg尝试birefnet-portrait(参见其他开源模型)——它在头发边缘质量更高但更慢更重。
参考
- CLI:
hyperframes remove-background - 评估:抠像评估 — v7
- 源模型:danielgatis/rembg
- ONNX 运行时:
onnxruntime-node