ꘇ top.edge
Extract lines with Sobel, Scharr or Laplacian — no model involved
- image
- image
Before there were learned line detectors, there were gradients. top.edge runs a classic edge filter on an image's luminance and hands you back a grey edge map with the original alpha intact. It's the model-free tool for "get me the linework": a sketch pass over a render, a wireframe read of a texture, a change-detector on two frames, or a cheap mask source for a later stage.
Worth naming what it is not: it doesn't do semantics. A learned preprocessor like an anime line extractor will pick out contours and drop the noise; a Sobel will happily draw an edge around every piece of film grain. For stylised lineart you still want the learned node - see the KB's ControlNet material - but for a fast, deterministic, dependency-free edge read, this is it.
How it works
The node takes luminance (weighted R/G/B, alpha-weighted, so transparent areas contribute nothing) and runs one of three filters over it, with clamped boundary sampling:
- sobel - the classic 3×3 gradient operator, the general-purpose default.
- scharr - same shape, stronger centre weighting, noticeably better rotational consistency. If your edges look like they break into axis-aligned chunks, Scharr cleans that up.
- laplacian - the second-derivative operator: a four-neighbour sum, absolute-valued. It responds to edges in every direction at once and looks like a thin, ringing outline rather than a gradient magnitude.
strength scales the response (0..8), threshold subtracts and renormalises (0..1, so contrast within the edge map rather than a hard cutoff), and invert flips black to white. The result is written to all three RGB channels - it's a greyscale image, not a one-channel mask - and the source alpha is preserved.
The inputs that matter
The algorithm combo and strength do 90% of the work. Start at sobel/1.0; raise strength before you raise threshold. Threshold is not a binning cutoff - think of it as lifting the black point of the edge response, which is how you drop faint grain response without erasing real lines.
One output, image. Common next stops: top.composite with multiply to lay the edges over the source as a sketch, top.colormap for a false-colour read, or top.channels if you need the luma as an actual alpha.
Install
Manager → search ꘇ Genereti → install, or:
git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt
Restart Comfy, refresh the browser. Requirements: one frontend pin. No model files, no camera permissions, no services - which is the honest appeal of this node versus a ControlNet annotator, which needs weights on disk. It registers as ꘇ top.edge under Genereti / TOP; the name starts with a glyph that sorts badly, so search genereti.
Traps
The output is RGB grey, not a MASK. If the next node wants a one-channel mask, you need a conversion - top.channels can route a luma or a channel into alpha, and top.mask accepts a native MASK too.
Transparent regions don't produce edges. Luminance is alpha-weighted, so a cut-out subject has no edge where its alpha ends. That's usually right (no bounding-box ghost), but if you wanted the silhouette itself, use the alpha channel instead.
Grain amplification. Every one of these filters responds to noise. If your source is a grungy photo, blur first - an edge pass on noisy input is a noise pass with extra steps.
Live vs Queue. Live chains run on the browser's GPU via WebGPU; Queue uses the PyTorch path. Live intermediates are 8-bit, Queue keeps float, so a high-strength edge pass can look slightly different between the two backends.
The pack is early alpha - the README says back up your workflows before updating, and means it.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| algorithm | COMBO | 3 options: sobel, scharr, laplacian | |
| strength | FLOAT | 1.000–8 | — |
| threshold | FLOAT | 0.000–1 | — |
| invert | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |