Outline
Four-way offset convolution, no OpenCV required
- imga
- IMAGE
Outline turns edges into lines. Feed it a depth map (or any image with meaningful transitions) and it returns a line-art version: bright where the signal changes sharply, black where it's flat. This is edge detection done the old-school way - no neural net, no OpenCV import, just four shifted copies of the image and a subtraction. The README describes it as "four-way offset convolution," which sounds fancy and is actually exactly that.
Here's the mechanism, and it's worth understanding because it's the entire node: the image is shifted one pixel left, right, up, and down. The four shifted copies are averaged, then the original image is subtracted. Where the image is flat, the average of the shifts equals the original, so the difference is zero - black. Where there's an edge, one of the shifts crosses it while the average lags behind, so the difference spikes - bright. Sum the four offsets and you get edges in every direction.
How it works
The pre-filled formula:
- Scales the image:
imga = np.clip(imga * pfloat1, 0, 1)- this is wherepfloat1("Depth Map Subdivision" in the tooltip, default 10) comes in. It multiplies the input before outlining. For a depth map, that amplifies the depth step before edges are found, so small depth breaks become visible lines. At the default 10, a depth range of 0–1 gets spread wide. - Shifts via
np.rollwith the edge pixels restored (so it doesn't wrap around). - Averages the four shifts, subtracts the original, and applies a sign flip if
pint1is negative - so a negative width outlines dark edges instead of bright ones. - Snaps with
np.ceil(result - 0.005)to clean up noise.
Inputs
imga- the input (depth map, mask, or any single-channel-ish image).pint1- Outline Width, in offset pixels, -32 to 32. Default 1. This is the shift distance - higher = thicker lines. Negative flips the edge polarity.pfloat1- Depth Map Subdivision, 0.05–100, default 10. The pre-gain described above.
One IMAGE output.
Install
ComfyUI Manager → search "FuncAsTexture", or:
cd ComfyUI/custom_nodes
git clone https://github.com/CoiiChan/ComfyUI-FuncAsTexture-CoiiNode
# restart ComfyUI
No models, no requirements.txt. Category: FunctionAsTexture.
Where it fits
This is the pack's bridge to the depth-estimation world. ComfyUI's depth models (MiDaS, etc.) give you smooth grayscale depth maps, and Outline is the quickest way to turn one into line art for a style-transfer or a sketch-pass conditioning. The pfloat1 gain exists specifically because raw depth maps are low-contrast; you need to amplify before you can trace.
Gotchas
- It outlines value changes, not objects. Flat regions give nothing; only edges survive. If your input is a normal photo, the output looks like a messy photocopy - feed it a depth or mask instead and it behaves.
pint1beyond a few pixels makes lines that look chunky rather than sharp, because you're averaging increasingly separated copies.- The output is a mask-like image, fine for feeding into image-conditional nodes, but if the pack's Clamp or a threshold comes after it, that's expected - the raw outline values are small.
It's the only real "filter" in this pack of math nodes, and it's a good one. If you've been loading OpenCV nodes just to get a Sobel, Outline does the equivalent in a drag-and-drop and stays inside the same pack.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| formula | STRING | imga = np.clip(imga * pfloat1,0,1) int_shift = abs(pint1) height, width = imga.shape[1:3] # 左偏移 img_left = np.roll(imga, int_shift, axis=2) img_left[:, :, :int_shift, :] = imga[:, :, :int_shift, :] # 右偏移 img_right = np.roll(imga, -int_shift, axis=2) img_right[:, :, -int_shift:, :] = imga[:, :, -int_shift:, :] # 上偏移 img_up = np.roll(imga, int_shift, axis=1) img_up[:, :int_shift, :, :] = imga[:, :int_shift, :, :] # 下偏移 img_down = np.roll(imga, -int_shift, axis=1) img_down[:, -int_shift:, :, :] = imga[:, -int_shift:, :, :] # 求和并计算轮廓 sumimgs = img_left + img_right + img_up + img_down redir = 0 if pint1 < 0: redir = 1 result = (sumimgs / 4 - imga) * ((-1) ** redir) result = np.ceil(result - 0.005) | — |
| pint1 | INT | 1-32–32 | Outline Width ,Number of offset pixels |
| pfloat1 | FLOAT | 10.000.05–100 | Optional,Depth Map Subdivision. |
| imgaopt | IMAGE | 可选,参考尺寸,默认 =(1,512,512,3) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |