cv2.convertMaps
Turn float remap maps into the fast fixed-point pair
- map1
- map2
- dstmap1
- dstmap2
Who this is for
cv2.remap takes a map of "for each output pixel, where do I read from?" and does the resampling. That map comes in two flavours: the readable one (two float32 arrays: x and y) and the fast one (a single packed int16 pair plus a uint16 interpolation-coefficient table). cv2.convertMaps converts between them.
So the pitch is: build your warp once in float, convert it to the fixed-point form once, then remap many images with the faster representation. If you're distorting one image, this node is pure overhead - there's nothing to amortise. If you're applying the same lens correction across a video batch, or running the same warp in a loop, it can be worth the extra step. The author's own tooltip puts the gain at roughly 30% faster remap for the fixed-point form.
It's a raw wrapper from ComfyUI CV (bmad4ever/comfyui_cv), category image/CV/low-level/cv2 C. The pack also ships a whole curated remap.py family (identity/lens/cylinder/relative maps) built around exactly this trick, with the design note: "Maps compose in NPARRAY space and collapse into ONE cv2.remap pass." If you're doing warp work, read that module's docs before hand-rolling maps.
How it works
In: map1 and map2. Out: dstmap1 and dstmap2. The conversion is bidirectional.
- Float → fixed. Give it float32 maps (
CV_32FC1for both) and ask forCV_16SC2: you get a packed int16 x/y map plus aCV_16UC1coefficient map. Fewer bytes, integer indexing, faster remap. - Fixed → float. Give it the packed pair and ask for
CV_32FC1: you get the maps back in plain float, which is what you need if you want to inspect or edit them in NPARRAY space.
The subtlety is nninterpolation. The fixed-point pair is only valid for one interpolation mode. If the map will be consumed with INTER_NEAREST, that flag must be set at conversion time - get it wrong and the coefficient table doesn't match how the map is used, which shows up as subtle edge tearing rather than an error.
Fixed-point also quantises. The int16 map resolves to fractions of a pixel, not to floats, so a warp that needs sub-pixel precision beyond that will lose something in the conversion.
Inputs and outputs that matter
- map1 - required, NPARRAY only.
CV_16SC2,CV_32FC1orCV_32FC2. The author's tooltip is explicit: a data array, not an image. - map2 - required, NPARRAY only.
CV_16UC1,CV_32FC1, or an empty matrix - that last case matters, because the packedCV_16SC2form carries x and y in a single map and leaves nothing formap2. - dstmap1type - required COMBO, defaulting to
CV_16SC2 (fixed-point, faster remap), withCV_32FC1 (float32, standard)as the other option. This is the direction switch. - nninterpolation - optional BOOLEAN, default
False, an advanced input. SetTruewhen the fixed-point maps will be used with nearest-neighbour. - dstmap1, dstmap2 - the converted pair, ready for
cv2.remap.
Build the input maps with the pack's remap.py nodes or with cv2.initUndistortRectifyMap; consume the output with cv2.remap.
Installing the pack
Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart. Requirements: Python ≥ 3.12, a ComfyUI on the V3 node API, and opencv-contrib-python-headless~=5.0.0.93. Behaviour is curated against that pinned OpenCV build specifically.
Where people get burned
- Converting for a single remap. The conversion cost is real and the saving only exists across repetition. One image → skip it.
nninterpolationleftFalsewhile remapping withINTER_NEAREST. No error, just wrong resampling along sharp edges. Decide the interpolation mode before you convert, not after.- Empty
map2surprises. Both sockets are required. The packed form legitimately wants an empty second map, so wire something that can express "empty" - the pack's array nodes - rather than leaving a required socket dangling. - Expecting a visible result. Both outputs are NPARRAY data. There is nothing here to preview; the pixels only appear once you remap.
- Losing precision you actually needed. If your warp is doing sub-pixel work on high-frequency detail - texture, fine text - check the fixed-point version against the float one before committing to it.
- Pack caveats. LLM-assisted development, acknowledged overfitting risk, no planned updates, "not recommended in production" without independent review - and no community corpus behind the pack at all (a Reddit search comes back empty). That matters more for a node like this than for
cv2.circle: an obscure optimisation path is exactly where an untested assumption survives. The pack's own docs are the best reference to read first, because they were written by the same process.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| map1 | NPARRAY | The first input map of type CV_16SC2, CV_32FC1, or CV_32FC2 . A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| map2 | NPARRAY | The second input map of type CV_16UC1, CV_32FC1, or none (empty matrix), respectively. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| dstmap1type | COMBO | CV_16SC2 (fixed-point, faster remap) | Type of the first output map that should be CV_16SC2, CV_32FC1, or CV_32FC2 . |
| nninterpolationopt | BOOLEAN | false | Flag indicating whether the fixed-point maps are used for the nearest-neighbor or for a more complex interpolation. Preset to the OpenCV default (False). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| dstmap1 | NPARRAY | — |
| dstmap2 | NPARRAY | — |