ComfyUI-LASED-mask
LASED (Learning Ant Swarm Edge Detection) nodes: a colour-region-aware, learnable edge/contour extractor with a sticky-latch masking mode. Swarm Edge, Multi-Seed, Food Map, Overlay, Animate and Point Picker nodes.
ComfyUI-LASED-mask
LASED — Learning Ant Swarm Edge Detection as ComfyUI custom nodes: a colour-region-aware,
learnable edge/contour extractor (an alternative to Canny/HED), with a masking mode that
latches the swarm's answer into a clean, exportable MASK.
You pick a point on the image; a seeded swarm of Snake-style ants spawns there, adopts that pixel's colour as a target, and — confined to that colour region — naturally drifts to and walks along the region's boundary, depositing pheromone. The accumulated edge-pheromone field is the output edge map. Because LASED finds the border of a colour blob rather than intensity gradients, it often gives exactly the contour a user means when they "click a region".
Algorithm contract: LASED-grounding.md
(the upstream LASED repository); the masking mode implements the Stage 2
sticky-latch / freeze / cleanup design proven in the LASED desktop app (v0.6.0).
Install
Clone into your ComfyUI custom_nodes folder:
cd ComfyUI/custom_nodes
git clone https://github.com/MushroomFleet/ComfyUI-LASED-mask
Dependencies: numpy (always present in ComfyUI). scipy is used when available for faster
diffusion and component labelling; everything falls back to pure numpy without it.
Nodes (category: LASED)
| Node | Inputs | Outputs | Purpose |
|---|---|---|---|
| LASED Swarm Edge | IMAGE, seed point, params | IMAGE edge map, MASK | One-shot run: spawn at a point, simulate, return the edge-pheromone field. |
| LASED Multi-Seed | IMAGE, seeds ("x,y; x,y; ..."), params | IMAGE, MASK | One swarm per colour region; edge fields merged (max), masks unioned. |
| LASED Food Map | IMAGE, food MASK, seed point, params | IMAGE, MASK | The mask is standing food/reward: the swarm is biased toward (and reinforces) your chosen contours — the offline analogue of interactive "success clicks". |
| LASED Overlay | IMAGE, edge IMAGE, colour, alpha | IMAGE | Glowing-contour composite for previews. |
| LASED Animate | IMAGE, seed point, params, frames | IMAGE batch | The simulation as frames — feed to video-combine / preview-animation nodes. |
| LASED Point Picker | IMAGE, point | seed_x INT, seed_y INT, point_str STRING | Visual point-and-click seed picker: the image shows inside the node, click to place the crosshair, wire the outputs into the swarm nodes. |
LASED Point Picker
Picking seed_x/seed_y by hand is fiddly, so the LASED Point Picker node shows the
input image inside the node and turns a click into coordinates:
- Connect the same
IMAGEthat feeds your swarm node to the picker'simageinput. - Press ↻ refresh preview. If the image traces back to a
LoadImage/LoadImageMask, the file is shown instantly with no execution; otherwise the picker queues a partial execution of just its upstream subgraph (needs ComfyUI ≥ 0.3.41). Running the full workflow once also (re)loads the preview. - Click (or drag) on the preview to place the crosshair — the live pixel readout is shown
bottom-left. The choice is stored in the
pointwidget as image fractions (0.5,0.5), so it stays valid if the image is swapped for a different resolution; you can also type absolute pixels (values > 1) by hand. - On the swarm node, convert the
seed_x/seed_ywidgets to inputs and connect the picker's INT outputs. Thepoint_stroutput ("x,y") can feed Multi-Seed'sseedsfield via a string-concat node when collecting several picks.
Classic vs masking mode
Every swarm-running node has a mode switch:
classic— the reference LASED behaviour. TheMASKoutput is the normalised edge-pheromone field thresholded atmask_threshold. The live field evaporates by design, so the mask reflects the field exactly as the run ended.masking(default) — the Stage 2 sticky-latch pipeline. A persistent mask layer latches any cell whose edge pheromone crossessticky_threshold× the field maximum at deposit time; latched cells never decay. When the run ends (orfreeze_afterticks fire first) the simulation freezes and a cleanup pass runs: morphological closing of 1–2 px gaps, then connected-component filtering that keeps the dominant contour(s) and drops stray-ant speckle. TheMASKoutput is that cleaned binary mask — ready for inpainting, compositing, or as a ControlNet scribble/contour hint.no_decayadditionally stops edge-pheromone evaporation (explore pheromone still fades, so anti-clumping keeps working).
Parameters worth knowing (grounding §10)
| Param | Default | Effect |
|---|---|---|
| tolerance | 40 | Colour tolerance τ — the most important knob. Lower = tighter region. Lab distances run smaller; try 10–25 there. |
| ants / steps | 250 / 600 | More = denser, more complete contours. |
| color_space | rgb | lab traces one continuous boundary where RGB fragments under uneven lighting. |
| hand | both | Wall-following handedness; both splits the swarm into CW + CCW cohorts. |
| beta / epsilon | 4.0 / 0.05 | Softmax greediness / random-move floor. |
| seed | 0 | All randomness is seeded — same seed + params ⇒ identical output, batch item i runs with seed + i. |
| max_side | 512 | Simulation grid cap (grounding §3.1); outputs are resampled back to input resolution. 0 = full res. |
Coordinates (seed_x/seed_y, multi-seed points) are in input-image pixels.
Example workflows
Every node has a drop-in example in workflows/ — open one in ComfyUI, point LoadImage
at any picture, set the seed coordinates to a pixel inside the colour region you want
traced, and queue.
lased_smoke.json— smoke test: LASED Swarm Edge → LASED Overlay → save (overlay + raw edge map).lased_multi_seed.json— LASED Multi-Seed: one swarm perx,y; x,ypoint, merged edge field overlaid plus the union mask saved viaMaskToImage.lased_food_map.json— LASED Food Map: a secondLoadImageMaskprovides the food MASK (paint bright where you want the contour rewarded), biasing the swarm toward those edges.lased_animate.json— LASED Animate: captures the contour emerging over the run and saves it withSaveAnimatedWEBP.lased_point_picker.json— LASED Point Picker driving LASED Swarm Edge: refresh the preview, click the region you want traced, queue.
Tests
The simulation core (lased_core.py) is torch- and ComfyUI-free, with acceptance tests
mirroring the upstream plans (seeded determinism, latch coverage, mask persistence, TTF
freeze, cleanup behaviour, classic-mode regression):
python tests/test_core.py # or: pytest tests/
Provenance
lased_core.pyis the referenceLASED.pyfrom the LASED repository with the Stage 2 masking mode added. Classic mode keeps the reference RNG stream and field updates byte-for-byte, so cross-implementation agreement per seed holds against the Python, TypeScript and Rust cores.- Node family per grounding §11; deferred there as stub I-01 and built here as its own project.
License
Apache-2.0 (same as the upstream LASED repository).