CV Warp Flags
Stop typing WARP_RELATIVE_MAP into eight different nodes
- flags
- value
OpenCV's warp functions don't take "bilinear" as a parameter. They take a bitmask: INTER_BILINEAR | WARP_RELATIVE_MAP | WARP_FILL_OUTLIERS, each flag one bit in one integer. In this pack you mostly meet it as the flags field on the generated cv2_remap, cv2_warpAffine, cv2_warpPerspective and cv2_warpPolar wrappers - a text field where typing the wrong combination is silent until your warp comes out scrambled.
CV Warp Flags is the node that authors that value once, correctly, and fans it out to as many warp nodes as you like.
How it works
In the UI the flags widget renders as a base dropdown plus one toggle per flag - you pick the interpolation from the dropdown and tick the modifiers, and the node emits the pipe-joined string. The execute is a one-liner: resolve the names (which validates them - a typo is a loud error rather than a silently ignored bit) and OR the bits into an integer.
Two outputs:
- flags - the pipe-joined string. Wire it into the
flagsinput of anycv2_remap/cv2_warpAffine/cv2_warpPerspective/cv2_warpPolarnode. One authored value, many consumers; that's the entire reason the node exists. - value - the resolved integer. For raw
intflag parameters, or for feedingMathExpressionif you're assembling a mask by hand.
The available bits are the superset across all four functions: INTER_NEAREST / INTER_LINEAR / INTER_CUBIC / INTER_LANCZOS4 as the base, plus WARP_RELATIVE_MAP, WARP_FILL_OUTLIERS, WARP_INVERSE_MAP and WARP_POLAR_LOG as toggles. Each function ignores bits it doesn't use - WARP_POLAR_LOG only means anything to warpPolar - so one authored value can serve a remap in one place and a polar warp in another without lying to either.
The one flag that matters
WARP_RELATIVE_MAP is a newer OpenCV 5 addition and it's the reason the pack's whole remap family hangs together. Without it, cv2_remap treats its two maps as absolute source coordinates: for every destination pixel, "read the source at this exact location." That's fine for a fixed warp, and it's why the chain starts at CV Identity Map.
With it, the maps are offsets. That's what lets you start from CV Relative Identity Map (all zeros) and stack distortions additively - CV Wave Map, CV Vector Displacement Map, pinch, radial, flow - each one adding to the coordinate maps before a single final remap. Compose the maps, resample once. The alternative is remapping the image four times and losing a bit of sharpness each pass.
Get this flag wrong and the symptom is distinctive: instead of a wavy image you get a uniform shift, a smear toward a corner, or a screen full of border colour. If a remap chain looks catastrophically wrong rather than subtly wrong, check the flags before you check the geometry.
Installing it
Manager → ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart. Python ≥ 3.12, recent ComfyUI on the V3 node API, and opencv-contrib-python-headless~=5.0.0.93 - behaviour is curated against that pinned version, and WARP_RELATIVE_MAP specifically is an OpenCV 5 flag that doesn't exist in older builds. That's the real gotcha with this node: on a 4.x cv2 it's not "slightly different", it's absent. GPL-3.0, forked from opencv-comfyui. No models.
Where people get burned
Editing the widget by hand. The string output is exactly what the raw wrappers' flags field accepts, so you can type it yourself - but then you've given up the validation, which is the actual value here.
Mixing a flags string with the wrong function. The bitmasks are compatible, so nothing errors. A WARP_POLAR_LOG in a remap is just ignored. That's by design and occasionally confusing when you expect a failure.
Assuming the wrappers' default is sane. A raw cv2_remap wrapper with no flags wired uses its own default, which won't be WARP_RELATIVE_MAP. Relative-coordinate map chains need this node, every time.
Forgetting the interpolation is part of it. NEAREST versus CUBIC changes your output as much as any toggle, and it's in the same widget. Masks and index maps want nearest; photographs want something smoother.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| flags | STRING | INTER_LINEAR | Pipe-joined cv2 constant names, e.g. "INTER_LINEAR | WARP_RELATIVE_MAP". In the UI this renders as a base dropdown with one toggle per flag. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| flags | STRING | The pipe-joined flags string - wire it into the flags input of cv2_remap / cv2_warpAffine / cv2_warpPerspective / cv2_warpPolar nodes. |
| value | INT | The resolved integer (constants OR-ed together). |