Nodes/ComfyUI Schematic/Schematic Overlay
ComfyUI Node

Schematic Overlay

Turn any render into annotated technical data-art — one node, no model, no API

By jeremieLouvaert·Created 2 months ago·Updated 19 days ago· 0
Schematic Overlay
  • image
  • pixelate_mask
  • texture
  • texture_mask
  • image
  • overlay_only
  • overlay_alpha
detection_modecombined
block_size16
threshold30
max_circles80
min_distance40
shapecircle
min_radius4
max_radius24
circle_stroke1.0
seed42
label_size8
overlay_opacity1.00
connection_dist150
line_weight0.8
chain_enabledtrue
chain_count11
chain_angle45
chain_base_radius250
chain_ratio0.79
chain_intersectionstrue
chain_intersection_size5.0
crosshair_enabledtrue
crosshair_frame_size60
crosshair_dash8
crosshair_stroke1.0
crosshair_star_size40
crosshair_star_points4
pixel_size16
zone_size100
pixel_stroketrue
image_opacity0.85
texture_opacity0.50
frame_text_size12
frame_text_tlDesign & Strategy
frame_text_trAKURATE
frame_text_bl
frame_text_br
palettewhiteOnDark
size_presetmatch input
bg_color#0a0a0a
stroke_color#d8d8d8
pixelate_zones

You know the look: a photo drained into white-on-dark, then buried under detection circles, dashed crosshairs, connection lines, coordinate labels and little pixelated zones - like a page torn out of a technical manual. ComfyUI can prompt that aesthetic into a generation, but it comes out half-baked, with gibberish labels and wobbly geometry. Schematic Overlay is the deterministic route: it takes an image you already have and draws the whole annotation apparatus over it in one node. No model, no API key, nothing to download besides the pack - it runs on Pillow, which is CPU-only and fast.

This is a post-processing node, not a generator. It sits at the end of a workflow, after VAE decode: feed it the render (or photo) you actually like, and it stylizes it into "technical data-art" while never touching the pixels outside its own overlay marks. If you want product renders to read as engineering documentation, or a logo shot as a "strategy diagram," this is the fastest route that doesn't involve retraining anything.

How it works

The engine is a grid analysis. The image is split into block_size squares (default 16px), each block gets a score, and blocks above threshold become circle candidates. The detection_mode picks the scoring: combined (the default) multiplies contrast by brightness deviation; contrast, bright, and dark each score a single measure. max_circles caps how many get placed and min_distance enforces spacing so they don't cluster - the whole thing is the classic "detected features on a technical plate" illusion. Circle size is driven by the detection score (between min_radius and max_radius) plus a seeded jitter, so seed changes the distribution of sizes without moving the centers.

Then the ornamentation layers stack on. connection_dist draws straight lines between every pair of circles within that range (set it to 0 to hide lines). The chain_* inputs draw a tangent chain of circles radiating from the canvas center with a shrinking or growing radius per step, plus optional intersection markers with coordinate labels. The crosshair_* group is the dashed full-canvas cross, the dashed centered square frame, and a center asterisk. Pixelation zones get placed either from a coordinate string (pixelate_zones as "x,y;x,y") or from a mask - each connected white region's centroid becomes a zone center. An optional texture image is screen-blended over the whole canvas (if you leave it unplugged and texture_opacity is above zero, a seeded procedural grain fills in), and the four frame_text_* corners give you the studio-slate label look.

The inputs that matter

  • image - the source photo. Required, and it's the only input you truly can't live without.
  • detection_mode, threshold, max_circles, min_distance - the four knobs that decide whether the circles look like a sparse, confident diagram or a dense cloud.
  • seed - reseed the circle-size jitter and the grain fallback. Deterministic per seed.
  • palette - four built-ins (whiteOnDark, blackOnLight, goldOnDark, greenOnDark) plus custom, which turns on the bg_color / stroke_color hex pair. Note that custom only applies when palette is set to custom.
  • size_preset - match the input, or cover-fit (crop-to-fill, centered) into fixed presets like Square, Landscape 16:9, or Instagram Story. Handy when you're templating for a social slot.

Outputs and where they wire

Three outputs, all from the pack's shared pipeline:

  • image - the full composite: background, photo, pixelation, crosshair, connections, circles, frame text, texture, chain, in that order.
  • overlay_only - the same stack with the photo removed, so the vector layer can be composited onto anything else.
  • overlay_alpha - a 0-to-1 MASK of everywhere a vector element (crosshair, connections, circles, frame text, chain) was drawn. Handy for downstream masking - say, only grain or darken the annotated areas.

Install

Via ComfyUI Manager (search "ComfyUI Schematic"), or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/jeremieLouvaert/ComfyUI-Schematic

Restart ComfyUI and both nodes show up under AKURATE/Schematic. The only declared dependency is Pillow>=9.0, which ComfyUI already ships - so no model downloads and no pip side-show. (Schematic Voronoi in the same pack uses scipy, but scipy ships with ComfyUI too.)

Where people get tripped up

The pack is new (first commit August 2026), so there's no backlog of community war-stories - but the grounded gotchas are worth knowing. Circles coming out too sparse? Drop threshold or raise max_circles. Lines everywhere? That's connection_dist - set it lower, or 0 to disable. Want your custom colors to actually show? palette must be custom. And if you're batching video frames, the texture input uses frame 0 for every frame - a per-frame texture won't animate, so connect one or accept the grain fallback. One genuinely nice touch: the same seed produces the same plate every run, so you can tweak one widget and get exactly one clean change.

CategoryAKURATE/Schematic

Inputs (46)

NameTypeDefaultDescription
imageIMAGE
detection_modeCOMBOcombinedCircle placement scoring mode. Combined = contrast x brightness deviation (default). Contrast, Bright, Dark score blocks by that single measure.
block_sizeINT168–64Analysis grid resolution - smaller = more detail
thresholdINT300–80Min score to place a circle - higher = fewer, stronger hits
max_circlesINT8020–400Cap on total circles placed
min_distanceINT4010–200Spacing between circle centers - prevents clustering
shapeCOMBOcircleDetection circle outline shape
min_radiusINT41–40Smallest circle size (low-score regions)
max_radiusINT244–120Largest circle size (high-score regions)
circle_strokeFLOAT1.00.1–8Circle outline thickness
seedINT420–4294967295Random seed for size variation - change for different distributions
label_sizeINT84–48Font size of x,y coordinate labels
overlay_opacityFLOAT1.000–1Master opacity for all circles, lines, dots, and text
connection_distINT1500–500Circles within this range get connected - 0 hides lines
line_weightFLOAT0.80.1–8Thickness of connecting lines
chain_enabledBOOLEANtrueEnable the tangent chain of circles radiating from canvas center
chain_countINT110–40Number of circles in the chain
chain_angleINT450–90Direction of chain - 0 vertical, 45 diagonal, 90 horizontal
chain_base_radiusINT25020–1000Size of the center circle
chain_ratioFLOAT0.790.3–1.2Size multiplier per step - below 1 shrinks outward
chain_intersectionsBOOLEANtrueDraw intersection markers where consecutive chain circles overlap
chain_intersection_sizeFLOAT5.00.5–20Dot size at each adjacent-circle intersection
crosshair_enabledBOOLEANtrueEnable the dashed crosshair, frame square, and center asterisk
crosshair_frame_sizeINT6010–100Square size as % of canvas short side
crosshair_dashINT81–40Length of each dash + gap
crosshair_strokeFLOAT1.00.1–8Line thickness for frame and crosshair
crosshair_star_sizeINT400–300Diameter of the center asterisk - 0 hides it
crosshair_star_pointsINT42–12Number of crossing lines - 2 is a plus, 4 is an 8-pointed star
pixel_sizeINT161–80Mosaic block size - larger = blockier
zone_sizeINT10010–500Half-width of each square pixelation zone
pixel_strokeBOOLEANtrueDraw an outline around each pixelation zone
image_opacityFLOAT0.850–1Fade the background image
texture_opacityFLOAT0.500–1Opacity of the noise overlay (screen blend)
frame_text_sizeINT126–72Font size of the 4 corner labels
frame_text_tlSTRINGDesign & StrategyTop-left corner frame text
frame_text_trSTRINGAKURATETop-right corner frame text
frame_text_blSTRINGBottom-left corner frame text
frame_text_brSTRINGBottom-right corner frame text
paletteCOMBOwhiteOnDarkColor palette for background and stroke color
size_presetCOMBOmatch inputCanvas size. 'match input' keeps the source image dimensions; presets cover-fit (crop-to-fill, centered) the source before resizing
bg_colorSTRING#0a0a0aCustom palette background color (hex). Used when palette = custom
stroke_colorSTRING#d8d8d8Custom palette stroke color (hex). Used when palette = custom
pixelate_zonesSTRINGPixelation zone centers as 'x,y;x,y;...' in canvas pixels. Union with pixelate_mask centroids
pixelate_maskoptMASKOptional mask; each 8-connected white region's centroid becomes a pixelation zone center
textureoptIMAGEOptional texture/noise image, screen-blended over the canvas. If empty and texture_opacity > 0, a procedural grain fallback is used
texture_maskoptMASKContinuous modulator for the texture screen blend; white = full texture, black = none; frame 0 used for batches

Outputs (3)

NameTypeDescription
imageIMAGE
overlay_onlyIMAGE
overlay_alphaMASK