Nodes/Anymatix/Anymatix Mask To SAM coord
ComfyUI Node

Anymatix Mask To SAM coord

Turn a mask into SAM click-points, so you can re-segment anything

By Anymatix·Created about a year ago·Updated 2 days ago· 0
Anymatix Mask To SAM coord
  • mask
  • pos_str
  • neg_str
individual_objectstrue

SAM (Segment Anything) is brilliant at one thing: you give it a click inside an object and it hands you back a clean mask of that object. The annoying part is producing the click. If you already have a mask - from a segmenter, a paint-in, or CLIPSeg - and you want SAM to refine it, hand-typing coordinates is misery. AnymatixMaskToSAMcoord converts the mask you've got into the point prompts SAM wants, as ready-to-paste JSON. It's the bridge between "whatever made this mask" and "SAM2's point-prompt input."

This is a genuinely common pattern in ComfyUI, and the KB's masking essay frames it well: a promptable segmenter is just another detector, and its output can drive the same SAM/SEGS refinement loops people use for detailing. The Anymatix README confirms the lineage - the approach follows Glidias' mask2sam, and the polygon maths here is the Bayazit convex decomposition ported from poly_decomp.py.

How it picks its points

For each mask in the batch, it labels connected regions and does two passes. For every region it finds a reference point - and this is the clever bit. Rather than blindly using the centroid (which for a crescent-shaped or U-shaped region can land outside the actual object), it decomposes the contour into convex pieces via Bayazit decomposition and picks the centroid of the largest valid convex piece. The result is a point that reliably lands inside the region even when the region is concave. That's the difference between a SAM click that carves the object and a click that keeps grabbing the background.

The second pass builds negative points - soft (partial) regions that SAM should treat as "not this" - and when individual_objects is on (the default), each positive point gets paired with its nearest negative rather than sharing one global negative. That matters in a crowded scene: a shared negative near region A can sit inside region B's territory, and nearest-pairing keeps every region's negative local to it.

Inputs, outputs, and the polarity gotcha

  • mask (MASK) - the source mask.
  • individual_objects (BOOLEAN, default true) - pair each positive with its own nearest negative.

Two STRING outputs, both JSON arrays of {"x": x, "y": y} points in mask-pixel coordinates: pos_str and neg_str. Wire them into a SAM node's point-prompt input.

Now the part the docs don't warn you about: this node puts its positive points on the regions where the mask is exactly 0, and its negatives on the nonzero (foreground) regions. That's the opposite of the white-object-on-black convention most segmenters emit, and it's easy to feed it a mask and get your positives and negatives swapped. If your SAM results are consistently wrong, don't debug SAM - flip the mask before it reaches this node. Worth one test run to confirm your convention.

Install

Part of anymatix-comfy-nodes. Manager: search "anymatix-comfy-nodes", install, restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/Anymatix/anymatix-comfy-nodes

It needs shapely and scikit-image, both of which the pack declares in its requirements - Manager installs them automatically, and a hand clone should pip install -r requirements.txt. The consumer side - actual SAM segmentation - is a separate pack (the Anymatix SAM2 loader wraps kijai's ComfyUI-segment-anything-2), so plan on installing that too.

CategoryAnymatix

Inputs (2)

NameTypeDefaultDescription
maskMASK
individual_objectsBOOLEANtrue

Outputs (2)

NameTypeDescription
pos_strSTRING
neg_strSTRING