Nodes/ComfyUI CV/cv2.getDerivKernels
ComfyUI Node

cv2.getDerivKernels

Sobel is two 1-D filters glued together — here they are separately

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.getDerivKernels
    • kx
    • ky
    ◄dx0►
    ◄dy0►
    ◄ksize0►
    ◄normalizetrue►
    ◄ktypeCV_32F►

    cv2.Sobel is not one convolution, it's two: a small derivative kernel in one direction multiplied by a smoothing kernel in the other, applied separately because a separable filter is much cheaper than an N×N one. cv2.getDerivKernels hands you those two pieces and nothing else.

    dx=1, dy=0, ksize=3   ->   kx = [-1, 0, 1]     ky = [1, 2, 1]
    

    That's the classic Sobel, split. dx=0, dy=1 swaps which axis gets the derivative. Ask for ksize=-1 and you get the Scharr pair instead, [-1, 0, 1] against [3, 10, 3] - better rotational symmetry, which is why Scharr is the one people recommend when 3×3 Sobel is too direction-biased.

    The inputs

    • dx, dy - derivative order in x and y. Required, and they open at 0, which is a valid "smooth this axis" request.
    • ksize - aperture: 1, 3, 5, 7, or -1 for Scharr. It opens at 0 and 0 is not a legal aperture, so a fresh node with untouched defaults will throw at execution. If getDerivKernels errors on you, this is almost always why. Even values are rejected too.
    • normalize - optional, on by default. The docs are unusually explicit about when to turn it off: if you're differentiating an 8-bit image into a 16-bit result and want to keep every fractional bit, normalize = false gives you the un-scaled integer coefficients.
    • ktype - CV_32F or CV_64F. Float32 is plenty for 8-bit sources; 64-bit is for when the rest of your chain is double.

    Two outputs, and the schema conveniently names them: kx (row filter) and ky (column filter). Both are NPARRAY.

    What you do with them

    The main one is cv2.sepFilter2D: feed kx and ky in and you get the exact derivatives that Sobel/Scharr would have produced, with the two-pass cost instead of the full convolution. For a 3×3 that's academic; for a 7×7 with a heavy smoothing axis it's real work saved per frame. The pack wires this as a subgraph blueprint so you don't have to remember which output goes in which slot.

    The second use is inspection. These arrays are the ground truth for "what does this derivative really compute", and looking at them once beats guessing why your gradient magnitudes are dimmer than expected - the smoothing axis is where the energy goes.

    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. Python ≥ 3.12, recent ComfyUI on the V3 node API. No models. Worth verifying the kernels in your own environment if you're doing anything numeric with them:

    python -c "import cv2; print(cv2.getDerivKernels(1, 0, 3))"
    

    Where people get burned

    • ksize = 0 throws, and the default is 0. The error message is cv2's terse "one of the arguments' values is out of range", which doesn't point at the aperture.
    • Same with even apertures. 4 isn't an approximate 3; it's rejected.
    • normalize silently changes your numbers. The kernels are differently scaled, so a downstream threshold tuned on one setting is wrong on the other. Pick one and stay on it. The pack's tooltip on this parameter carries OpenCV's own rationale for the 16-bit case.
    • These are kernels, not pictures. Wiring kx into an image preview gets you a normalised grey blur. Send them to sepFilter2D (or filter2D), and use Inspect CV Data when you want to actually read the numbers.
    • Don't forget these are the unnormalised pairing mental model: one axis differentiates, the other smooths. If both dx and dy are non-zero you're asking for a mixed derivative, which is legal but rarely what anyone means.
    Categoryimage/CV/low-level/cv2 G

    Inputs (5)

    NameTypeDefaultDescription
    dxINT0-2147483648–2147483647Derivative order in respect of x.
    dyINT0-2147483648–2147483647Derivative order in respect of y.
    ksizeINT0-2147483648–2147483647Aperture size. It can be FILTER_SCHARR, 1, 3, 5, or 7.
    normalizeoptBOOLEANtrueFlag indicating whether to normalize (scale down) the filter coefficients or not. Theoretically, the coefficients should have the denominator $=2^{ksize*2-dx-dy-2}$. If you are going to filter floating-point images, you are likely to use the normalized kernels. But if you compute derivatives of an 8-bit image, store the results in a 16-bit image, and wish to preserve all the fractional bits, you may want to set normalize=false . Preset to the OpenCV default (True).
    ktypeoptCOMBOCV_32FType of filter coefficients. It can be CV_32f or CV_64F .

    Outputs (2)

    NameTypeDescription
    kxNPARRAY—
    kyNPARRAY—