cv2.getGaborKernel
A kernel that finds stripes at exactly the angle and spacing you pick
- ksize
- nparray
A Gabor kernel is a sinusoid multiplied by a Gaussian. That sounds academic and has an extremely concrete behaviour: it responds strongly to parallel stripes of a particular spacing at a particular orientation, and barely at all to anything else. Convolve an image with one and you get a "how much does this patch look like that texture" map.
This node builds the kernel. It doesn't filter anything - its single nparray output is the kernel, which you then hand to cv2.filter2D (Gabor isn't separable, so sepFilter2D isn't the tool here).
The inputs
ksize- kernel size(w, h), usually square and usually large enough to hold the envelope plus a couple of wavelengths.(31, 31)is a typical starting point for the parameters below. It opens at(0, 0), which isn't a kernel.sigma- standard deviation of the Gaussian envelope. Bigger sigma, bigger receptive patch; if you keep the kernel smaller than about 4–6 sigma across, you're truncating the envelope and the kernel won't behave like the maths says.theta- orientation of the stripes, in radians. This is the knob that makes the node interesting:0,π/4,π/2are horizontal, diagonal and vertical.lambd- the wavelength of the sinusoid, in pixels. This is your spacing selector: pick a value near the period of the texture you're hunting.gamma- spatial aspect ratio.1.0is a round envelope; smaller values elongate it so the kernel is directional along the stripes too.psi- phase, optional, defaulting toπ/2. The phase decides whether the kernel is odd-symmetric (strong response on edges and step changes) or even-symmetric (line and bar detector). The defaultπ/2is the edge-sensitive one;0flips it to the line-detector behaviour.ktype-CV_32ForCV_64Ffor the kernel coefficients.
Every required numeric input opens at 0, and sigma = theta = lambd = gamma = 0 is a degenerate kernel, so a fresh node needs real numbers before it means anything. A reasonable first set: ksize (31, 31), sigma 4, theta 0, lambd 10, gamma 0.5, psi π/2.
What you'd use it for
- Texture gating. Halftone screens, moiré from a re-photographed display, scan lines, woven fabric, wood grain: run a small bank of kernels at several angles and thresholds and you have a mask that says "screen here, real content there". That's a genuinely useful pre-filter before an upscale or a restoration pass, and it costs milliseconds.
- Orientation features. Six angles × two frequencies gives you twelve energy values per pixel, which is a crude but real descriptor for ridge direction.
- Ridge finding. Set
lambdnear the ridge spacing and the kernel becomes a matched filter for fingerprints, cracks, or printed hatching.
This is the deterministic-primitive layer in full effect: no model, no seed, no VRAM. Compare that with reaching for a segmentation model to find a halftone pattern, and the cost difference is absurd.
Install
Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Restart ComfyUI. Python ≥ 3.12, recent ComfyUI on the V3 node API. Nothing to download.
Where people get burned
- Zeroed defaults. All five required numbers start at 0 and the node will happily try to build a nonsense kernel. Fill them in.
- Angles in radians, not degrees.
theta = 45is not "45 degrees" - it's radians, i.e. a cramped wrap-around. It won't error, it'll just look wrong. Use0.785for 45°. - A kernel that's too small for its own wavelength. With
lambdat 20 and a 15-pixel kernel, most of each stripe is outside the window and the response is mush. - Wiring the kernel somewhere that expects a picture. It's an NPARRAY, and the pack's preview nodes will min-max normalise it into a grey blob. Send it to
filter2D; check its contents withInspect CV Datawhen you want to see what it actually looks like. - Expecting
sigmato behave like a blur radius. It's the envelope's standard deviation inside a bandpass, not a smoothing knob - cranking it widens the patch and lowers the frequency selectivity at the same time.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| ksize | CV_TUPLE | 0,0 | Size of the filter returned. One value with 2 components (w, h) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place. |
| sigma | FLOAT | 0.0000-1e+38–1e+38 | Standard deviation of the gaussian envelope. |
| theta | FLOAT | 0.0000-1e+38–1e+38 | Orientation of the normal to the parallel stripes of a Gabor function. |
| lambd | FLOAT | 0.0000-1e+38–1e+38 | Wavelength of the sinusoidal factor. |
| gamma | FLOAT | 0.0000-1e+38–1e+38 | Spatial aspect ratio. |
| psiopt | FLOAT | 1.5708-1e+38–1e+38 | Phase offset. Preset to the OpenCV default (1.5707963267948966). |
| ktypeopt | COMBO | CV_64F | Type of filter coefficients. It can be CV_32F or CV_64F . |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |