Nodes/ComfyUI Assistant Node/PVL Gemini 2.5 Segmentation
ComfyUI Node

PVL Gemini 2.5 Segmentation

Ask Gemini 2.5 for a mask, not a caption

By pvlprk·Created about a year ago·Updated 10 months ago· 1
PVL Gemini 2.5 Segmentation
  • image1
  • image2
  • image3
  • image4
  • image5
  • mask1
  • mask2
  • mask3
  • mask4
  • mask5
  • labels_json1
  • labels_json2
  • labels_json3
  • labels_json4
  • labels_json5
◄api_key►
◄modelgemini-2.5-flash►
◄temperature0.7►
◄tries3►
◄timeout45►
◄seed0►
◄mask_threshold0.50►
◄combine_maskstrue►
◄mask_blur0►
◄mask_expand0►
◄debugfalse►
◄show_full_json_debugfalse►
◄debug_max_preview_chars1200►
◄prompt1►
◄prompt2►
◄prompt3►
◄prompt4►
◄prompt5►

Every segmentation node in this pack asks a specialist model - SAM-3, Moondream - to find an object. This one does something weirder: it asks a generalist vision-language model to segment, and Gemini 2.5 is surprisingly good at it. You give it an image and a prompt like "the red car" and it returns an actual MASK, not a description. That's the kind of trick that sounded absurd when people first tried it and works disturbingly well on clean subjects.

Why reach for it over a dedicated segmenter? No segmentation model download, and - the real kicker - it's prompted with natural language. SAM needs point/box prompts or GroundingDINO-style text; Gemini just needs a sentence. If you want masks that follow "everything except the person in the background," Gemini's understanding of that instruction beats most specialist pipelines' parsing of it.

How it works

The node sends each image+prompt pair to Google's generateContent endpoint, asks the model to produce a mask, then converts the returned data into a ComfyUI MASK tensor. Up to five image/prompt pairs run independently, each producing its own mask output and its own labels_json - so you get the segmentation AND the model's text labels for each region.

The post-processing knobs are where the practical tuning lives:

  • mask_threshold (0.5) - binarizes the model's soft mask. Lower it if the mask is losing thin structures.
  • combine_masks (on) - merge the model's per-region masks into one per image. Off if you want separate objects.
  • mask_blur (0) and mask_expand (0) - smooth or dilate/erode the result. Negative mask_expand erodes; positive dilates. Tiny nudges fix the ragged edges you get from language-segmentation.

The inputs that matter

  • image1 … image5 and prompt1 … prompt5 - up to five independent segmentation jobs per node. Each promptN pairs with its imageN.
  • model - gemini-2.5-flash (default) or gemini-2.5-pro. Flash is much cheaper; pro for hard scenes.
  • api_key - blank defaults to GEMINI_API_KEY.
  • temperature (0.7), tries (3), timeout (45), seed - engine knobs. tries defaults higher here because segmentation responses can be flaky.
  • debug, show_full_json_debug, debug_max_preview_chars - the debug trio; turn on show_full_json_debug when a mask comes back empty to see what the model actually returned.

Outputs: mask1 … mask5 (MASK) and labels_json1 … labels_json5 (STRING).

Installing it

Standard pack install:

cd ComfyUI/custom_nodes
git clone https://github.com/pvlprk/comfyui-pvl-api-nodes

Restart, set GEMINI_API_KEY or fill the field. No models download; Gemini runs on Google's infrastructure.

Common issues

The honest limitation is that this is a language model doing a geometry task. On clean subjects it's great; on cluttered scenes with thin boundaries it produces masks that need the blur/expand cleanup, and sometimes it just returns a coarse region. If a mask comes back all-black, enable the debug outputs and look at what JSON the model sent - usually it either refused ("not enough context") or produced a degenerate polygon. Second, combine_masks on vs off changes what you get on the mask ports; if regions are missing, check that toggle before blaming the prompt. Finally, costs: five images × flash is cheap, but gemini-2.5-pro with retries is not - keep the pro model for the one hard image, not the whole grid.

Categoryimage/segmentation

Inputs (23)

NameTypeDefaultDescription
api_keySTRING—
modelCOMBOgemini-2.5-flash2 options: gemini-2.5-flash, gemini-2.5-pro
temperatureFLOAT0.70–2—
triesINT31–10—
timeoutINT455–300—
seedINT00–2147483647—
mask_thresholdFLOAT0.500–1—
combine_masksBOOLEANtrue—
mask_blurINT00–64—
mask_expandINT0-64–64—
debugBOOLEANfalse—
show_full_json_debugBOOLEANfalse—
debug_max_preview_charsINT1200200–20000—
image1optIMAGE—
prompt1optSTRING—
image2optIMAGE—
prompt2optSTRING—
image3optIMAGE—
prompt3optSTRING—
image4optIMAGE—
prompt4optSTRING—
image5optIMAGE—
prompt5optSTRING—

Outputs (10)

NameTypeDescription
mask1MASK—
mask2MASK—
mask3MASK—
mask4MASK—
mask5MASK—
labels_json1STRING—
labels_json2STRING—
labels_json3STRING—
labels_json4STRING—
labels_json5STRING—