MultiObjectMask
A Mask for Every Wall, Floor, and Sofa (from a Segmentation Map)
- image
- MASK
MultiObjectMask takes a semantic-segmentation image - the flat-color "label map" where every pixel is painted as a category - and hands you back a mask of exactly the objects you name. Type wall, floor, get a mask covering just the walls and floor. It's the node you want when you're doing virtual staging or interior re-deco: select the walls to re-paint them, the floor to swap the flooring, the sofa to reupholster it, all without hand-painting a single region.
It ships in ComfyUI-LyraVSIH (the "VSIH" being virtual-staging-in-home territory), a one-node pack from pbpbpb2705 / lyra-research. Fair warning on reputation: this is a small, single-commit personal utility, not a community staple - you won't find it in "essential packs" lists, and that's fine. It does one thing and does it by color lookup.
How it works
The trick is a bundled CSV. The repo ships data.csv, which is the ADE20K SceneParse150 object table - 150 classes (wall, floor, ceiling, bed, sofa, sky…) each with its palette color code. That's the same palette OneFormer, Mask2Former, and SegFormer scene-parsing models paint with.
When you run the node, it:
- Splits your
room_objectstring on commas. - Looks each keyword up in that table's Name column, case-insensitively, including the
;-separated synonyms ("floor" matchesfloor;flooring, "car" matchescar;auto;automobile…). - Finds the palette RGB for the class, then scans the image for pixels exactly equal to that color.
- Sums the per-class masks and clamps to 1, so multiple objects union together.
No model, no API, no downloads - it's pure color matching against a lookup table. The mask comes out at image resolution with crisp, exact edges.
The two inputs that matter
There are only two, and both are worth understanding before you wire this up:
image- this is not your photo. It must be a segmentation map with the flat ADE20K palette colors. The matcher has zero tolerance: a real photograph has no pixel exactly(120, 120, 120), so feeding one in returns nothing.room_object(multiline string) - comma-separated object names from the table. It's case-insensitive and synonym-aware, and unknown names are silently skipped. Checkdata.csvin the pack folder to see what's actually available - it's 150 ADE20K classes, so there's no "toaster" and the plant pot ispot;flowerpot.
The single output, MASK, wires into anything that eats a mask: SetLatentNoiseMask for classic masked inpainting, InpaintModelConditioning for a Flux-style inpaint pass, or a mask preview node to see what you got.
Installing it
ComfyUI Manager is the easy path: search "ComfyUI-LyraVSIH" and hit install. Or by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/pbpbpb2705/ComfyUI-LyraVSIH
then restart ComfyUI. Dependencies are genuinely light - requirements.txt asks for pandas, torch, and torchvision. torch and torchvision are already in any working ComfyUI install, so the only real new dependency is pandas. There are no model files to fetch; the CSV rides along in the repo. (The pyproject.toml lists a heap of extra packages, but the runtime code only touches torch, torchvision, pandas, and the standard library - ignore the rest.)
Where people get burned
- Feeding in a photo. The most common failure, and the one that produces an empty result. You need a segmentation map upstream - OneFormer is the usual source, and it's the standard segmentation preprocessor in the ecosystem (also the basis of semantic-segmentation ControlNet conditioning).
- Everything returns empty and the node errors. If none of your keywords match the table, the function returns
Noneand downstream nodes choke. Check the spelling, checkdata.csv, and remember it'sbednotmattress,sofa;couch;loungenot "couch" only. - Edges too hard. Exact-color matching gives you knife-sharp boundaries, which look terrible pasted straight into an inpaint. Run the mask through a blur/feather (4–12px is the usual range) before it hits the sampler.
- A segmentation map painted by a different palette. Anything that isn't ADE20K colors will silently match nothing. If your upstream model uses a different palette, this node can't know.
For a workflow built around it, the modern move is: seg map in → MultiObjectMask → feather → Inpaint Crop + Stitch (or a direct inpaint) so the only pixels that change are the ones you named. That's the one thing masked inpainting still owns outright - everything outside the mask stays bit-identical.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| room_object | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |