cv2.createHanningWindow
The window you multiply an image by before phase correlation
- winSize
- nparray
cv2.createHanningWindow builds a 2-D Hann (Hanning) window - a smooth bump that's 1 in the middle and falls to 0 at the edges, sampled on a grid you specify. On its own it's just an array of numbers. Its job in life is to be multiplied into an image before a Fourier-domain operation, so that the image's edges don't create a big artificial discontinuity in the spectrum.
Concretely, in this pack: you use it before cv2.phaseCorrelate, which estimates the translation between two images. Multiply both images by the window first and the measured shift stops being polluted by edge wrap-around. That's the same reason a window function exists in audio, and it's the only reason you'd reach for this node in ComfyUI.
It's cv2.createHanningWindow in bmad4ever's ComfyUI CV pack, category image/CV/low-level/cv2 C - one of the ~470 auto-generated cv2.* wrappers, so expect a bare, uncurated cv2 signature rather than a friendly "window size" preset.
How it works
For a winSize of (W, H), the array is w(x) · w(y) with w(n) = 0.5 · (1 − cos(2πn/(N−1))) - a raised cosine that's zero at both ends and 1 at the centre. OpenCV fills it as a single-channel float array; there's no input image involved, so this node generates data out of two widgets.
Multiplying an image by it tapers the borders to black, which is what you want: phase correlation is a circular cross-correlation, so an image whose left edge doesn't match its right edge contributes a phantom shift. The window removes that assumption by construction. It does throw away border information, so it's a trade - the standard one, and the reason it's the first line of every phase-correlation example.
The inputs and outputs that matter
winSize is a two-component CV_TUPLE (width, height) with a useless default of (0, 0) - set it to your image size. Both dimensions must be greater than 1. You can wire it from CV Tuple if the size comes from elsewhere (cv2.getOptimalDFTSize on your image dimensions is the fussy-correct way to pick it) or just type the pair in.
type is the created array's depth, defaulting to CV_32F, and the tooltip is blunt: "Created array type". Stay on CV_32F. The dropdown is the pack's shared depth list, so it also offers integer depths and "same as input" - but there's no input to inherit a depth from here, and the function is implemented for the float types. The default is preset for a reason.
The single output is an NPARRAY named nparray - a single-channel float32 array, not an IMAGE. Multiply it into your image with cv2.multiply (both operands need matching size and channel count; the window is 1-channel, so either make a 3-channel window with CV Concat Arrays on the last axis, or apply it per channel), then hand the windowed pair to cv2.phaseCorrelate.
Practical shape of the graph:
Image → cv2.multiply(win) ─┐
├→ cv2.phaseCorrelate → shift (x, y) + response
Image → cv2.multiply(win) ─┘
cv2.createHanningWindow(winSize = image size) → win
CV AlignMTB and its sibling CV AlignMTBToReference are the curated, already-windowed descendants of this idea in the same pack - if all you want is "align these frames", start there and skip the plumbing.
Installing it
ComfyUI Manager → search the pack title (ComfyUI CV) → install → restart ComfyUI. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Python ≥ 3.12 and a recent ComfyUI on the V3 node API. The headless contrib wheel is the declared dependency because nothing in the pack uses imshow/waitKey; the same functions are in the GUI wheel if you already have it. What you must not do is install a non-contrib opencv-python over the top - all four distributions share one site-packages/cv2, and the contrib submodules silently disappear, taking every contrib node with them (tools/repair_opencv_contrib.py --check/--apply handles that).
Common issues and troubleshooting
(0, 0) window. The widget defaults are placeholders, not a sensible window. Set both dimensions to your image's size or the multiply will fail or produce nonsense.
The multiply errors on shape. A 1-channel window multiplied against a 3-channel IMAGE. Concat the window to three channels first, or keep everything in NPARRAY space and do it per channel.
Phase correlation now returns a shift of zero. Window too small or image too smooth - a heavily tapered window on a low-detail frame can leave nothing to correlate. Try the correlation without the window to confirm the pair is actually shifted, then reduce how aggressively you taper.
Zero-padding your images first? Then don't also window them - pad and window are two different fixes for the same edge-effect problem, and doing both usually makes the estimate worse while looking like diligence.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| winSize | CV_TUPLE | 0,0 | The window size specifications (both width and height must be > 1) 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. |
| type | COMBO | CV_32F | Created array type |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |