docs: say background removal can drop objects a person holds by miguel-heygen · Pull Request #6002 · heygen-com/hyperframes · GitHub
Skip to content

docs: say background removal can drop objects a person holds - #6002

Open
miguel-heygen wants to merge 1 commit into
mainfrom
docs/remove-background-held-objects
Open

miguel-heygen wants to merge 1 commit into
mainfrom
docs/remove-background-held-objects

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What changed

The remove-background guide now says the included model can drop all or part of an object a person holds (a dark microphone, phone, card or instrument), and adds a "Part of a held object is missing" row to Common problems. The CLI's default model stays u2net_human_seg. No code changes.

Why

A user reported that background removal on a person holding a dark microphone made parts of the mic transparent. u2net_human_seg is a people-only model. We measured whether a general-purpose model should replace it, with the rule to switch only if a candidate gave better edges and was no slower per frame. None was. The quality win is real, but the cheapest candidate is 2.8x slower, so the default stays and the guide now names the case.

What I measured

Candidates, with preprocessing and ONNX files exactly as rembg v2.0.85 rembg/sessions/*.py (md5 of every download matched rembg's):

model input normalisation output download
u2net_human_seg (today) 320 ImageNet mean/std min-max 168 MB
isnet-general-use 1024 mean 0.5, std 1.0 min-max 171 MB
birefnet-general-lite 1024 ImageNet mean/std sigmoid, then min-max 214 MB
birefnet-general 1024 ImageNet mean/std sigmoid, then min-max 928 MB

Every model ran through the CLI's own createSession / process path (onnxruntime-node 1.21.1, CPU provider, graphOptimizationLevel: "all"). Model choice and per-model preprocessing were patched into a local copy only.

Ground truth. I used seven green-screen clips of people from Mixkit (Mixkit Stock Video Free License), five of them holding something: a dark handheld mic (28293), a black bass guitar (23862), black phones (28311, 28286, 24388) and a black card (9099). Clip 28287 has no object. A chroma key gave the ground-truth alpha, and each frame was composited over one of three real plates (meadow, street with bikes, dark alley). That is 45 frames per clip, 315 frames in all. Metrics: IoU of the matte at 0.5, mean absolute alpha error, the same error inside a 10 px band around the true edge, false-positive rate, and recall inside a hand-set box around each held object. No clips are committed.

Edge quality, on the 141 frames scored for all three practical models:

model IoU MAE edge MAE false-pos held-object recall
u2net_human_seg 0.926 0.0121 0.130 0.0033 0.913
isnet-general-use 0.938 0.0096 0.106 0.0032 0.960
birefnet-general-lite 0.977 0.0033 0.056 0.0014 0.988

On all 315 frames, u2net vs isnet scored IoU 0.956 vs 0.959, edge MAE 0.109 vs 0.094, and held-object recall 0.912 vs 0.932. On the 15 frames where the full BiRefNet ran: IoU 0.978, edge MAE 0.052, against lite's 0.977 and 0.055 on the same frames.

Held-object recall by clip (all 315 frames, u2net / isnet): mic 0.982 / 0.996, card 0.780 / 0.790, bass 0.902 / 0.958, phone 0.984 / 0.983. In the contact sheets, u2net leaves see-through bands across the mic handle on some frames, drops the card entirely, and drops the guitar body. isnet keeps the objects but softens the body on the card clip, and picks up a background bike and a stand-mounted boom mic. BiRefNet-lite keeps the held objects cleanly. That last point matters for the captions skill, which relies on u2net leaving boom arms out of the matte (skills/embedded-captions/references/anti-patterns.md).

Speed, ms per frame through process(). This covers the model run plus the input/output resizes and alpha composite at 1280x720, with the first 5 frames dropped as warm-up. All models ran at the same thread settings: intraOpNumThreads: 2, interOpNumThreads: 1, one process at a time, on a shared 8-core Linux x86_64 machine under other load. The numbers are relative, not absolute.

model median p90 vs u2net peak RSS frames timed
u2net_human_seg 754 ms 782 ms 1.0x 1.1 GB 100
isnet-general-use 2092 ms 2234 ms 2.8x 1.9 GB 100
birefnet-general-lite 9594 ms 10140 ms 12.7x 11.4 GB 22
birefnet-general 21469 ms 25068 ms 28x 13.5 GB 10

A u2net rerun after the others gave a 632 ms median, so the box got quieter, not busier. The ratios above are, if anything, kind to the candidates. An earlier pass at onnxruntime's default thread count put isnet at 1.7x (315 frames) and BiRefNet-lite at about 14x (8-frame probe).

Verdict: BiRefNet wins on edge quality and held objects, but is 13x to 28x slower and needs about 11 GB of RAM. isnet is slightly better on edges but 2.8x slower, with new false positives. None passes "no slower", so the default stays.

What I did NOT exercise

  • CoreML (the default on Apple Silicon) and CUDA. Speed ratios on those providers were not measured.
  • A dedicated, quiet machine. The timings are relative only.
  • The full BiRefNet on more than 15 quality frames and 10 timed frames. BiRefNet-lite was timed on 22 frames.
  • Bit-exactness of mattes across thread counts. Quality frames came from both the default-thread and 2-thread runs.
  • Natural footage scored against ground truth. Scored frames are green-screen composites, the chroma key is imperfect at hair and on a small spill spot, and frame-to-frame flicker was not scored. Plain (non-green) mic clips were only checked by eye.
  • The end-to-end CLI video encode. ffmpeg decode and encode cost the same for every model and were left out of the timing.

The included people-only model can drop all or part of a held microphone, phone,
card or instrument. Measured against isnet-general-use and BiRefNet (general and
lite): those keep held objects far better but run 2.8x to 28x slower per frame,
so the default stays and the guide now names the case.
@mintlify

mintlify Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟢 Ready View Preview Oct 21, 2026, 5:19 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 4bee2d52. This is docs only: three lines in docs/guides/remove-background.mdx.

  • The new wording is accurate. u2net_human_seg is a people-segmentation model, and the Common-problems row says exactly that ("matches people, not what they hold"). It is consistent with skills/embedded-captions/SKILL.md:261, which relies on the same model leaving boom arms out of the matte. The guide's "use another tool when" list is the right place for the held-object case, next to "the subject is a product".
  • Keeping the default is supported. The body's own rule was to switch only for better edges and no slowdown. Every candidate is at least 2.8x slower per frame, so the guide changes and the CLI default doesn't.
  • The table is unchanged in shape: the new row keeps the column widths.
  • CI: no check failed. Semantic PR title and regression are green. The code jobs (Build, Test, Typecheck, the Windows pair) skipped on their docs-only path filters.
  • Nit: the list says "another segmentation or masking tool" and the new row says "another matting tool". For a reader looking for one, skills/media-use/references/operations.md:54 already names heygen background-removal as the alternative.

Verdict: APPROVE
Reasoning: A correct, measured limitation note with no code change and nothing red.

— Via

This branch was successfully deployed

1 active deployment
staging - docs — 4bee2d52 Deployed Oct 21, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants