LASED Swarm Edge
LASED Swarm Edge
- image
- edge_map
- mask
Canny finds every edge in the image, and then you spend ten minutes fighting it. LASED Swarm Edge does the opposite: you click one color blob, and it comes back with the single contour around that blob. It's a different animal from the usual edge detectors, and for a specific job - "I want the boundary of this one region, not the whole picture" - it's the one you'll reach for.
LASED stands for Learning Ant Swarm Edge Detection, and the name isn't marketing. A seeded swarm of Snake-style ants spawns at your click point, adopts that pixel's color as its target, and is confined to that color region. The ants drift to the region's boundary and then wall-walk along it, depositing pheromone as they go. The accumulated edge-pheromone field is your edge map. Because the swarm follows the border of a color blob rather than intensity gradients, you get exactly the contour a human means when they point at something - which is why this pack's framing calls it an alternative to Canny/HED for region-based work.
The node takes an IMAGE plus a seed_x/seed_y pair - the "click", in input-image pixels, and it has to land inside the color region you want traced. Put it on the border and the swarm has nothing to lock onto. It outputs two things: edge_map (an IMAGE) and mask (a MASK). The edge map feeds LASED Overlay for the neon preview, or a ControlNet edge/scribble-style condition; the mask is your clean binary contour, ready for inpainting, compositing, or as a ControlNet scribble hint.
The few knobs that actually matter:
tolerance- the most important one. Colour tolerance for what counts as "the same region". Lower = tighter. If you're inlabcolor space, distances run smaller, so try 10–25 there.color_space-rgb(default),weighted, orlab.labtraces one continuous boundary where RGB fragments under uneven lighting. If your blob looks clean but the contour comes out broken, trylab.mode-classicormasking(default). Classic just thresholds the edge field atmask_threshold; the field evaporates by design, so the mask reflects the run's final state. Masking is the smarter Stage 2 pipeline: it latches any cell whose edge pheromone crossessticky_threshold× the field maximum at deposit time, latched cells never decay, and when the run freezes a cleanup pass closes 1–2px gaps and drops stray-ant speckle. For anything you want to export, keep masking.ants/steps- density and duration. More of both means denser, more complete contours, at a runtime cost.max_side- the simulation runs downsampled to at most 512px on the longest side (0 = full resolution) and outputs are resampled back. Big images get noticeably slower; leave it unless you need pixel-perfect detail.
One more: seed. All randomness is seeded, so the same seed + params gives you identical output every time - batch item i runs with seed + i. That ties into the classic ComfyUI seed trap: check the widget's control_after_generate isn't left on randomize if you're trying to reproduce a run.
Install
Nothing exotic here. Through ComfyUI Manager, search for ComfyUI-LASED-mask, or:
cd ComfyUI/custom_nodes
git clone https://github.com/MushroomFleet/ComfyUI-LASED-mask
then restart ComfyUI. The nodes appear under the LASED category. There are no model downloads, and the only real dependency is numpy, which every ComfyUI install already ships. scipy is used when present for faster diffusion and component labelling, and the code falls back to pure numpy without it - you generally don't need to pip-install anything. Every node ships a drop-in example in workflows/; lased_smoke.json wires Swarm Edge → Overlay → save.
Where people get burned
- Seed point outside the region. The swarm has no target colour to adopt, so you get noise instead of a contour. Click inside the blob.
- Fragmented contour in uneven light.
rgbsplits one logical region into several. Switchcolor_spacetolab. - Masking drops a contour you wanted. The cleanup keeps the dominant contour(s) and despeckles away the rest. If your target is a small or faint edge, lower
sticky_thresholdso more cells latch, or drop toclassicand tunemask_thresholdyourself.
One honest caveat: this pack is new and quiet - as of writing there's essentially no community war-story lore to lean on, so the README and a working example workflow are your friends. But the core is deliberately simple and deterministic, so it behaves predictably.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| seed_x | INT | 00–16384 | Spawn point x in input-image pixels (the 'click'). |
| seed_y | INT | 00–16384 | — |
| tolerance | FLOAT | 40.01–250 | Colour tolerance (tau). Lower = tighter region. Lab distances run smaller; try 10-25 there. |
| ants | INT | 2501–5000 | — |
| steps | INT | 6001–20000 | Simulation ticks. More steps = cleaner, more complete contours. |
| color_space | COMBO | rgb | 3 options: rgb, weighted, lab |
| hand | COMBO | both | Wall-following handedness; 'both' splits the swarm into clockwise and counter-clockwise cohorts. |
| beta | FLOAT | 4.00.1–12 | Softmax temperature. Higher = greedier edge following. |
| epsilon | FLOAT | 0.050–0.5 | Random-move floor; prevents the swarm freezing. |
| seed | INT | 00–18446744073709550000 | — |
| mode | COMBO | masking | classic: MASK = thresholded edge pheromone. masking (Stage 2): MASK = sticky-latched, gap-closed, despeckled contour. |
| mask_threshold | FLOAT | 0.150.01–0.95 | classic mode only: threshold on the normalised edge map for the MASK output. |
| sticky_threshold | FLOAT | 0.200.05–0.6 | masking mode: latch a cell when its edge pheromone crosses this fraction of the field maximum. |
| freeze_after | INT | 00–20000 | masking mode: freeze (and clean) the mask after this many ticks. 0 = run all steps, then freeze. |
| no_decay | BOOLEAN | false | masking mode: stop edge-pheromone evaporation entirely. |
| max_side | INT | 5120–4096 | Downsample the longest side to this for simulation (0 = full resolution). Outputs are resampled back. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| edge_map | IMAGE | — |
| mask | MASK | — |