Mask: SAM One-Click
SAM Without the Node Zoo
- image
- mask_hint
- mask
- score
- preview
Segment Anything is the model this whole ecosystem reaches for when it needs to mask a specific object rather than cut the foreground out. The catch has always been the plumbing: three nodes, a checkpoint loader, a coordinate-encoding node, and a fiddly little point-editor widget. This node collapses that into one box where the "click" is a string of text.
Mask: SAM One-Click (JHPixelProSAMMask) takes an image, a hint, and returns a mask, a quality score and a preview. If you've ever wanted Photoshop's Object Selection tool inside ComfyUI, this is the closest thing.
Why it's built this way
SAM is promptable segmentation: point at a pixel, draw a box, hand it a rough mask, and it returns a clean mask for whatever you pointed at, zero-shot. It generalises to objects nobody trained it on, which is why it's the backbone of targeted masking rather than a background remover.
The awkward part in ComfyUI is that there's no "click on the preview" widget. PixelPro's answer is to make the click textual, which sounds worse than it is - a point is [[x,y]], and if every coordinate is between 0 and 1 it's read as a fraction of the frame, so [[0.5, 0.45]] is slightly above centre at any resolution. That's resolution-independent and you can copy it between workflows, which is more than you can say for a click.
The three ways to point at something
Points. points_json for positive clicks on the object, negative_points_json for things that must stay out. Two or three points usually settles an ambiguous subject. One caveat the docs are explicit about: a list made only of 0s and 1s like [[1,1]] is read as pixels, because it's indistinguishable from pixel 1,1 - so use a real fraction like 0.5 if you mean a fraction.
A face box. Wire bbox_json from Face Detect or Face Detect Lite. It reads the {x, y, w, h, ...} list, and on a batch it picks the box whose batch_index matches each image. This is the fastest route to a portrait mask.
A rough mask. Anything that emits a MASK goes into mask_hint. Even a hand-drawn rectangle works - the node takes its bounding box plus a point inside it, and SAM tightens it to the real edges. That's a genuinely nice trick: it turns any garbage mask into a prompt.
Give it nothing at all and it clicks the image centre.
The settings that change your result
model - vit_b is the balanced default (375 MB, ~3 GB VRAM), mobile_sam is 39 MB and ~0.4 GB and fast enough on CPU, vit_l and vit_h are the accuracy end at 1.2 GB and 2.5 GB. A missing checkpoint downloads on first use into ComfyUI/models/sams/. Only one model stays resident; switching evicts the previous one.
multimask - on, SAM proposes three candidate masks and the best predicted IoU wins. That's the right setting for a single click, because one click is ambiguous and SAM's three guesses are often "the face", "the head" and "the whole person". Turn it off when you're giving a box or several points and want exactly one answer.
mask_threshold - a logit cut-off, 0 is SAM's default. Below 0 grows the mask, above 0 shrinks it. Try ±1 before you start adding more points.
keep_model_loaded - on by default. Turn it off to free the VRAM straight after a run; note that ComfyUI's own Free memory button can't see this model, so it's the only lever you have.
Outputs
mask is the selection, one per image. score is SAM's own predicted quality - below about 0.7, add a point rather than accepting it; on a batch it's the average. preview is the image with the mask tinted and outlined, which is what you actually look at while placing points.
From there, mask is just a mask: inpainting, a Pyramid Blend composite, a colour grade through a gate. Worth knowing the limitation - SAM's edge is clean but binary. For hair and fur it's a starting point, not a finish; chain it into a sub-pixel refiner or an alpha-matting trimap flow.
Install
Manager: search ComfyUI-JH-PixelPro, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt
Then Add Node → ComfyUI-JH-PixelPro → mask. The pack wants Python 3.10+, kornia>=0.7 (SAM runs through Kornia's VisualPrompter, which is why the version floor exists), MediaPipe, OpenCV headless and SciPy. Weights come from Meta's public buckets on first use; vit_b and mobile_sam are SHA256-verified, vit_l and vit_h are only size-checked because upstream publishes no hash.
Common issues
Score under 0.7 and a mask that grabbed half the background. Multimask picked a bigger candidate than you wanted. Add a negative point, or drop from multimask on to off with a box.
Only part of the subject selected. Classic single-click behaviour - one click on a torso often returns just the shirt. Add a second positive point on the missing part.
First run hangs. It's downloading a few hundred MB. There's a socket timeout and a .part file, so a failed download retries cleanly instead of leaving a corrupt checkpoint.
The mask is right, the edge is crunchy. Expected. SAM resizes internally to 1024 px on the long side and scales the mask back up, so fine hair isn't recoverable from SAM alone - refine afterward.
Out-of-memory on vit_h. 2.5 GB of encoder plus whatever the rest of your graph holds. Use vit_b, or turn keep_model_loaded off and run in a queue once.
There's no community trail for this pack - search the subreddits and you'll find nothing - so treat the per-node docs (English and Vietnamese, with source notes) as the support channel. For a SAM wrapper that's fine; the model behaviour is Meta's, not the pack's.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Image to cut the object out of. | |
| model | COMBO | vit_b | SAM checkpoint from ComfyUI/models/sams/. vit_b (375 MB, ~3 GB VRAM) is the balanced default, mobile_sam (39 MB, ~0.4 GB) is the fastest, vit_l (1.2 GB) and vit_h (2.5 GB) are the most accurate. A missing file is downloaded on first use. Only one model stays in VRAM. |
| points_json | STRING | Positive "clicks" on the object: [[x,y],[x,y]]. Pixels (0..size-1), or 0-1 fractions when every value is within 0-1 and at least one is a fraction such as 0.5 ([[1,1]] is pixel 1,1). Empty with no other prompt = image centre. | |
| negative_points_json | STRING | Points that must NOT be in the mask, same format. | |
| multimask | BOOLEAN | true | ON: SAM proposes 3 masks and the best predicted IoU is kept (good for a single click). OFF: one mask, better with a box or several points. |
| mask_threshold | FLOAT | 0.0-20–20 | Logit cut-off. 0 = SAM default. Lower grows the mask, higher shrinks it. |
| bbox_jsonopt | STRING | bbox_json from Face Detect / Face Detect Lite. Uses the entry matching the batch index (or the first one). | |
| mask_hintopt | MASK | Rough mask from any node: its bounding box and a point inside it become the prompt. | |
| keep_model_loadedopt | BOOLEAN | true | ON: keep the SAM model in VRAM for the next run (faster). OFF: free it right after this run (ComfyUI's Free memory button cannot see it). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |
| score | FLOAT | — |
| preview | IMAGE | — |